.gwave-pills { display:flex; flex-wrap:wrap; gap:.5rem; margin:.5rem 0 1rem; }
.gw-pill { position:relative; padding:.4rem .6rem; border-radius:999px; font:600 12px/1 system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial;
background:#0f172a; color:#dbeafe; border:1px solid rgba(148,163,184,.25); }
.gw-pill[data-variant="apy"]{ background:#052e16; color:#bbf7d0; border-color:rgba(74,222,128,.25);}
.gw-pill[data-variant="lock"]{ background:#1e1b4b; color:#e9d5ff; border-color:rgba(196,181,253,.25);}
.gw-pill[data-variant="points"]{ background:#0b1220; color:#c7d2fe;}
.gw-tip { position:absolute; z-index:50; left:50%; transform:translateX(-50%); bottom:calc(100% + 8px);
white-space:nowrap; padding:.45rem .6rem; border-radius:10px; font:500 12px/1.2 system-ui; background:#111827; color:#e5e7eb;
border:1px solid rgba(255,255,255,.08); opacity:0; pointer-events:none; transition:opacity .15s ease; }
.gw-pill:hover .gw-tip{opacity:1}
.gwave-pills { display:flex; flex-wrap:wrap; gap:.5rem; margin:.5rem 0 1rem; }
.gw-pill { position:relative; padding:.4rem .6rem; border-radius:999px; font:600 12px/1 system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial;
background:#0f172a; color:#dbeafe; border:1px solid rgba(148,163,184,.25); }
.gw-pill[data-variant="apy"]{ background:#052e16; color:#bbf7d0; border-color:rgba(74,222,128,.25);}
.gw-pill[data-variant="lock"]{ background:#1e1b4b; color:#e9d5ff; border-color:rgba(196,181,253,.25);}
.gw-pill[data-variant="points"]{ background:#0b1220; color:#c7d2fe;}
.gw-tip { position:absolute; z-index:50; left:50%; transform:translateX(-50%); bottom:calc(100% + 8px);
white-space:nowrap; padding:.45rem .6rem; border-radius:10px; font:500 12px/1.2 system-ui; background:#111827; color:#e5e7eb;
border:1px solid rgba(255,255,255,.08); opacity:0; pointer-events:none; transition:opacity .15s ease; }
.gw-pill:hover .gw-tip{opacity:1}
APY:
—
Demo APY from pool/index data (not financial advice)
Lock:
—
Indicative lock period for staking program
Points:
—
Cumulative participation points (demo)
(async function(){
const pills = document.getElementById('gw-pills');
// Anchor: place after #kpi-live if present; else after first h1
try {
const kpi = document.getElementById('kpi-live');
const h1 = document.querySelector('h1');
if (kpi) kpi.insertAdjacentElement('afterend', pills);
else if (h1) h1.insertAdjacentElement('afterend', pills);
} catch {}
const REL = (p)=>'data/'+p, LOCAL = (p)=>'http://127.0.0.1:5199/'+p;
const getJSON = async (p)=> {
const tryOne = (u)=>fetch(u+(u.includes('?')?'&':'?')+'_cb='+Date.now(),{cache:'no-store'})
.then(r=>r.ok?r.json():Promise.reject());
try { return await tryOne(REL(p)); } catch { try { return await tryOne(LOCAL(p)); } catch { return null; } }
};
const pool = await getJSON('pool.json') || {};
const idx = await getJSON('index.json') || {};
// Points (from index.json if available)
const pts = (typeof idx.points === 'number') ? idx.points : null;
// Lock days (optional)
const lock = (typeof idx.lock_days === 'number') ? idx.lock_days : null;
// APY: prefer explicit idx.apy else demo from pool totals
let apy = (typeof idx.apy === 'number') ? idx.apy : null;
if (apy == null && typeof pool.total_earned === 'number' && typeof pool.total_staked === 'number' && pool.total_staked > 0){
apy = (pool.total_earned / pool.total_staked) * 100; // lifetime demo %
}
// Paint values
const setOrHide = (id, val, fmt=(x)=>x)=> {
const el = document.getElementById(id);
const wrap = el?.closest('.gw-pill');
if (!el || !wrap) return;
if (val==null || Number.isNaN(val)) { wrap.style.display='none'; return; }
el.textContent = fmt(val);
};
setOrHide('pill-apy-val', apy, (v)=> (v>=100? v.toFixed(0): v>=10? v.toFixed(1): v.toFixed(2)) + '%');
setOrHide('pill-lock-val', lock, (v)=> v + ' days');
setOrHide('pill-points-val', pts, (v)=> v.toLocaleString('en-AU'));
// If at least one pill visible, unhide the row
const visible = [...document.querySelectorAll('#gw-pills .gw-pill')].some(p=>p.style.display!=='none');
if (visible) pills.hidden = false;
// Wire Tokenomics button to open modal (inserted by Module B)
const btn = document.getElementById('pill-tokenomics');
if (btn) btn.addEventListener('click', ()=> {
const modal = document.getElementById('gw-tokenomics-modal');
if (modal) modal.showModal();
});
})();
🌊 GoodWave Staking — Devnet Live Demo
.gwave-pills { display:flex; flex-wrap:wrap; gap:.5rem; margin:.5rem 0 1rem; }
.gw-pill { position:relative; padding:.4rem .6rem; border-radius:999px; font:600 12px/1 system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial;
background:#0f172a; color:#dbeafe; border:1px solid rgba(148,163,184,.25); }
.gw-pill[data-variant="apy"]{ background:#052e16; color:#bbf7d0; border-color:rgba(74,222,128,.25);}
.gw-pill[data-variant="lock"]{ background:#1e1b4b; color:#e9d5ff; border-color:rgba(196,181,253,.25);}
.gw-pill[data-variant="points"]{ background:#0b1220; color:#c7d2fe;}
.gw-tip { position:absolute; z-index:50; left:50%; transform:translateX(-50%); bottom:calc(100% + 8px);
white-space:nowrap; padding:.45rem .6rem; border-radius:10px; font:500 12px/1.2 system-ui; background:#111827; color:#e5e7eb;
border:1px solid rgba(255,255,255,.08); opacity:0; pointer-events:none; transition:opacity .15s ease; }
.gw-pill:hover .gw-tip{opacity:1}
APY:
—
Demo APY from pool/index data (not financial advice)
Lock:
—
Indicative lock period for staking program
Points:
—
Cumulative participation points (demo)
(async function(){
const pills = document.getElementById('gw-pills');
// Anchor: place after #kpi-live if present; else after first h1
try {
const kpi = document.getElementById('kpi-live');
const h1 = document.querySelector('h1');
if (kpi) kpi.insertAdjacentElement('afterend', pills);
else if (h1) h1.insertAdjacentElement('afterend', pills);
} catch {}
const REL = (p)=>'data/'+p, LOCAL = (p)=>'http://127.0.0.1:5199/'+p;
const getJSON = async (p)=> {
const tryOne = (u)=>fetch(u+(u.includes('?')?'&':'?')+'_cb='+Date.now(),{cache:'no-store'})
.then(r=>r.ok?r.json():Promise.reject());
try { return await tryOne(REL(p)); } catch { try { return await tryOne(LOCAL(p)); } catch { return null; } }
};
const pool = await getJSON('pool.json') || {};
const idx = await getJSON('index.json') || {};
// Points (from index.json if available)
const pts = (typeof idx.points === 'number') ? idx.points : null;
// Lock days (optional)
const lock = (typeof idx.lock_days === 'number') ? idx.lock_days : null;
// APY: prefer explicit idx.apy else demo from pool totals
let apy = (typeof idx.apy === 'number') ? idx.apy : null;
if (apy == null && typeof pool.total_earned === 'number' && typeof pool.total_staked === 'number' && pool.total_staked > 0){
apy = (pool.total_earned / pool.total_staked) * 100; // lifetime demo %
}
// Paint values
const setOrHide = (id, val, fmt=(x)=>x)=> {
const el = document.getElementById(id);
const wrap = el?.closest('.gw-pill');
if (!el || !wrap) return;
if (val==null || Number.isNaN(val)) { wrap.style.display='none'; return; }
el.textContent = fmt(val);
};
setOrHide('pill-apy-val', apy, (v)=> (v>=100? v.toFixed(0): v>=10? v.toFixed(1): v.toFixed(2)) + '%');
setOrHide('pill-lock-val', lock, (v)=> v + ' days');
setOrHide('pill-points-val', pts, (v)=> v.toLocaleString('en-AU'));
// If at least one pill visible, unhide the row
const visible = [...document.querySelectorAll('#gw-pills .gw-pill')].some(p=>p.style.display!=='none');
if (visible) pills.hidden = false;
// Wire Tokenomics button to open modal (inserted by Module B)
const btn = document.getElementById('pill-tokenomics');
if (btn) btn.addEventListener('click', ()=> {
const modal = document.getElementById('gw-tokenomics-modal');
if (modal) modal.showModal();
});
})();
.gwave-pills { display:flex; flex-wrap:wrap; gap:.5rem; margin:.5rem 0 1rem; }
.gw-pill { position:relative; padding:.4rem .6rem; border-radius:999px; font:600 12px/1 system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial;
background:#0f172a; color:#dbeafe; border:1px solid rgba(148,163,184,.25); }
.gw-pill[data-variant="apy"]{ background:#052e16; color:#bbf7d0; border-color:rgba(74,222,128,.25);}
.gw-pill[data-variant="lock"]{ background:#1e1b4b; color:#e9d5ff; border-color:rgba(196,181,253,.25);}
.gw-pill[data-variant="points"]{ background:#0b1220; color:#c7d2fe;}
.gw-tip { position:absolute; z-index:50; left:50%; transform:translateX(-50%); bottom:calc(100% + 8px);
white-space:nowrap; padding:.45rem .6rem; border-radius:10px; font:500 12px/1.2 system-ui; background:#111827; color:#e5e7eb;
border:1px solid rgba(255,255,255,.08); opacity:0; pointer-events:none; transition:opacity .15s ease; }
.gw-pill:hover .gw-tip{opacity:1}
APY:
—
Demo APY from pool/index data (not financial advice)
Lock:
—
Indicative lock period for staking program
Points:
—
Cumulative participation points (demo)
(async function(){
const pills = document.getElementById('gw-pills');
// Anchor: place after #kpi-live if present; else after first h1
try {
const kpi = document.getElementById('kpi-live');
const h1 = document.querySelector('h1');
if (kpi) kpi.insertAdjacentElement('afterend', pills);
else if (h1) h1.insertAdjacentElement('afterend', pills);
} catch {}
const REL = (p)=>'data/'+p, LOCAL = (p)=>'http://127.0.0.1:5199/'+p;
const getJSON = async (p)=> {
const tryOne = (u)=>fetch(u+(u.includes('?')?'&':'?')+'_cb='+Date.now(),{cache:'no-store'})
.then(r=>r.ok?r.json():Promise.reject());
try { return await tryOne(REL(p)); } catch { try { return await tryOne(LOCAL(p)); } catch { return null; } }
};
const pool = await getJSON('pool.json') || {};
const idx = await getJSON('index.json') || {};
// Points (from index.json if available)
const pts = (typeof idx.points === 'number') ? idx.points : null;
// Lock days (optional)
const lock = (typeof idx.lock_days === 'number') ? idx.lock_days : null;
// APY: prefer explicit idx.apy else demo from pool totals
let apy = (typeof idx.apy === 'number') ? idx.apy : null;
if (apy == null && typeof pool.total_earned === 'number' && typeof pool.total_staked === 'number' && pool.total_staked > 0){
apy = (pool.total_earned / pool.total_staked) * 100; // lifetime demo %
}
// Paint values
const setOrHide = (id, val, fmt=(x)=>x)=> {
const el = document.getElementById(id);
const wrap = el?.closest('.gw-pill');
if (!el || !wrap) return;
if (val==null || Number.isNaN(val)) { wrap.style.display='none'; return; }
el.textContent = fmt(val);
};
setOrHide('pill-apy-val', apy, (v)=> (v>=100? v.toFixed(0): v>=10? v.toFixed(1): v.toFixed(2)) + '%');
setOrHide('pill-lock-val', lock, (v)=> v + ' days');
setOrHide('pill-points-val', pts, (v)=> v.toLocaleString('en-AU'));
// If at least one pill visible, unhide the row
const visible = [...document.querySelectorAll('#gw-pills .gw-pill')].some(p=>p.style.display!=='none');
if (visible) pills.hidden = false;
// Wire Tokenomics button to open modal (inserted by Module B)
const btn = document.getElementById('pill-tokenomics');
if (btn) btn.addEventListener('click', ()=> {
const modal = document.getElementById('gw-tokenomics-modal');
if (modal) modal.showModal();
});
})();
.gwave-pills { display:flex; flex-wrap:wrap; gap:.5rem; margin:.5rem 0 1rem; }
.gw-pill { position:relative; padding:.4rem .6rem; border-radius:999px; font:600 12px/1 system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial;
background:#0f172a; color:#dbeafe; border:1px solid rgba(148,163,184,.25); }
.gw-pill[data-variant="apy"]{ background:#052e16; color:#bbf7d0; border-color:rgba(74,222,128,.25);}
.gw-pill[data-variant="lock"]{ background:#1e1b4b; color:#e9d5ff; border-color:rgba(196,181,253,.25);}
.gw-pill[data-variant="points"]{ background:#0b1220; color:#c7d2fe;}
.gw-tip { position:absolute; z-index:50; left:50%; transform:translateX(-50%); bottom:calc(100% + 8px);
white-space:nowrap; padding:.45rem .6rem; border-radius:10px; font:500 12px/1.2 system-ui; background:#111827; color:#e5e7eb;
border:1px solid rgba(255,255,255,.08); opacity:0; pointer-events:none; transition:opacity .15s ease; }
.gw-pill:hover .gw-tip{opacity:1}
APY:
—
Demo APY from pool/index data (not financial advice)
Lock:
—
Indicative lock period for staking program
Points:
—
Cumulative participation points (demo)
(async function(){
const pills = document.getElementById('gw-pills');
// Anchor: place after #kpi-live if present; else after first h1
try {
const kpi = document.getElementById('kpi-live');
const h1 = document.querySelector('h1');
if (kpi) kpi.insertAdjacentElement('afterend', pills);
else if (h1) h1.insertAdjacentElement('afterend', pills);
} catch {}
const REL = (p)=>'data/'+p, LOCAL = (p)=>'http://127.0.0.1:5199/'+p;
const getJSON = async (p)=> {
const tryOne = (u)=>fetch(u+(u.includes('?')?'&':'?')+'_cb='+Date.now(),{cache:'no-store'})
.then(r=>r.ok?r.json():Promise.reject());
try { return await tryOne(REL(p)); } catch { try { return await tryOne(LOCAL(p)); } catch { return null; } }
};
const pool = await getJSON('pool.json') || {};
const idx = await getJSON('index.json') || {};
// Points (from index.json if available)
const pts = (typeof idx.points === 'number') ? idx.points : null;
// Lock days (optional)
const lock = (typeof idx.lock_days === 'number') ? idx.lock_days : null;
// APY: prefer explicit idx.apy else demo from pool totals
let apy = (typeof idx.apy === 'number') ? idx.apy : null;
if (apy == null && typeof pool.total_earned === 'number' && typeof pool.total_staked === 'number' && pool.total_staked > 0){
apy = (pool.total_earned / pool.total_staked) * 100; // lifetime demo %
}
// Paint values
const setOrHide = (id, val, fmt=(x)=>x)=> {
const el = document.getElementById(id);
const wrap = el?.closest('.gw-pill');
if (!el || !wrap) return;
if (val==null || Number.isNaN(val)) { wrap.style.display='none'; return; }
el.textContent = fmt(val);
};
setOrHide('pill-apy-val', apy, (v)=> (v>=100? v.toFixed(0): v>=10? v.toFixed(1): v.toFixed(2)) + '%');
setOrHide('pill-lock-val', lock, (v)=> v + ' days');
setOrHide('pill-points-val', pts, (v)=> v.toLocaleString('en-AU'));
// If at least one pill visible, unhide the row
const visible = [...document.querySelectorAll('#gw-pills .gw-pill')].some(p=>p.style.display!=='none');
if (visible) pills.hidden = false;
// Wire Tokenomics button to open modal (inserted by Module B)
const btn = document.getElementById('pill-tokenomics');
if (btn) btn.addEventListener('click', ()=> {
const modal = document.getElementById('gw-tokenomics-modal');
if (modal) modal.showModal();
});
})();
.gwave-pills { display:flex; flex-wrap:wrap; gap:.5rem; margin:.5rem 0 1rem; }
.gw-pill { position:relative; padding:.4rem .6rem; border-radius:999px; font:600 12px/1 system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial;
background:#0f172a; color:#dbeafe; border:1px solid rgba(148,163,184,.25); }
.gw-pill[data-variant="apy"]{ background:#052e16; color:#bbf7d0; border-color:rgba(74,222,128,.25);}
.gw-pill[data-variant="lock"]{ background:#1e1b4b; color:#e9d5ff; border-color:rgba(196,181,253,.25);}
.gw-pill[data-variant="points"]{ background:#0b1220; color:#c7d2fe;}
.gw-tip { position:absolute; z-index:50; left:50%; transform:translateX(-50%); bottom:calc(100% + 8px);
white-space:nowrap; padding:.45rem .6rem; border-radius:10px; font:500 12px/1.2 system-ui; background:#111827; color:#e5e7eb;
border:1px solid rgba(255,255,255,.08); opacity:0; pointer-events:none; transition:opacity .15s ease; }
.gw-pill:hover .gw-tip{opacity:1}
APY:
—
Demo APY from pool/index data (not financial advice)
Lock:
—
Indicative lock period for staking program
Points:
—
Cumulative participation points (demo)
(async function(){
const pills = document.getElementById('gw-pills');
// Anchor: place after #kpi-live if present; else after first h1
try {
const kpi = document.getElementById('kpi-live');
const h1 = document.querySelector('h1');
if (kpi) kpi.insertAdjacentElement('afterend', pills);
else if (h1) h1.insertAdjacentElement('afterend', pills);
} catch {}
const REL = (p)=>'data/'+p, LOCAL = (p)=>'http://127.0.0.1:5199/'+p;
const getJSON = async (p)=> {
const tryOne = (u)=>fetch(u+(u.includes('?')?'&':'?')+'_cb='+Date.now(),{cache:'no-store'})
.then(r=>r.ok?r.json():Promise.reject());
try { return await tryOne(REL(p)); } catch { try { return await tryOne(LOCAL(p)); } catch { return null; } }
};
const pool = await getJSON('pool.json') || {};
const idx = await getJSON('index.json') || {};
// Points (from index.json if available)
const pts = (typeof idx.points === 'number') ? idx.points : null;
// Lock days (optional)
const lock = (typeof idx.lock_days === 'number') ? idx.lock_days : null;
// APY: prefer explicit idx.apy else demo from pool totals
let apy = (typeof idx.apy === 'number') ? idx.apy : null;
if (apy == null && typeof pool.total_earned === 'number' && typeof pool.total_staked === 'number' && pool.total_staked > 0){
apy = (pool.total_earned / pool.total_staked) * 100; // lifetime demo %
}
// Paint values
const setOrHide = (id, val, fmt=(x)=>x)=> {
const el = document.getElementById(id);
const wrap = el?.closest('.gw-pill');
if (!el || !wrap) return;
if (val==null || Number.isNaN(val)) { wrap.style.display='none'; return; }
el.textContent = fmt(val);
};
setOrHide('pill-apy-val', apy, (v)=> (v>=100? v.toFixed(0): v>=10? v.toFixed(1): v.toFixed(2)) + '%');
setOrHide('pill-lock-val', lock, (v)=> v + ' days');
setOrHide('pill-points-val', pts, (v)=> v.toLocaleString('en-AU'));
// If at least one pill visible, unhide the row
const visible = [...document.querySelectorAll('#gw-pills .gw-pill')].some(p=>p.style.display!=='none');
if (visible) pills.hidden = false;
// Wire Tokenomics button to open modal (inserted by Module B)
const btn = document.getElementById('pill-tokenomics');
if (btn) btn.addEventListener('click', ()=> {
const modal = document.getElementById('gw-tokenomics-modal');
if (modal) modal.showModal();
});
})();
.gwave-pills { display:flex; flex-wrap:wrap; gap:.5rem; margin:.5rem 0 1rem; }
.gw-pill { position:relative; padding:.4rem .6rem; border-radius:999px; font:600 12px/1 system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial;
background:#0f172a; color:#dbeafe; border:1px solid rgba(148,163,184,.25); }
.gw-pill[data-variant="apy"]{ background:#052e16; color:#bbf7d0; border-color:rgba(74,222,128,.25);}
.gw-pill[data-variant="lock"]{ background:#1e1b4b; color:#e9d5ff; border-color:rgba(196,181,253,.25);}
.gw-pill[data-variant="points"]{ background:#0b1220; color:#c7d2fe;}
.gw-tip { position:absolute; z-index:50; left:50%; transform:translateX(-50%); bottom:calc(100% + 8px);
white-space:nowrap; padding:.45rem .6rem; border-radius:10px; font:500 12px/1.2 system-ui; background:#111827; color:#e5e7eb;
border:1px solid rgba(255,255,255,.08); opacity:0; pointer-events:none; transition:opacity .15s ease; }
.gw-pill:hover .gw-tip{opacity:1}
APY:
—
Demo APY from pool/index data (not financial advice)
Lock:
—
Indicative lock period for staking program
Points:
—
Cumulative participation points (demo)
(async function(){
const pills = document.getElementById('gw-pills');
// Anchor: place after #kpi-live if present; else after first h1
try {
const kpi = document.getElementById('kpi-live');
const h1 = document.querySelector('h1');
if (kpi) kpi.insertAdjacentElement('afterend', pills);
else if (h1) h1.insertAdjacentElement('afterend', pills);
} catch {}
const REL = (p)=>'data/'+p, LOCAL = (p)=>'http://127.0.0.1:5199/'+p;
const getJSON = async (p)=> {
const tryOne = (u)=>fetch(u+(u.includes('?')?'&':'?')+'_cb='+Date.now(),{cache:'no-store'})
.then(r=>r.ok?r.json():Promise.reject());
try { return await tryOne(REL(p)); } catch { try { return await tryOne(LOCAL(p)); } catch { return null; } }
};
const pool = await getJSON('pool.json') || {};
const idx = await getJSON('index.json') || {};
// Points (from index.json if available)
const pts = (typeof idx.points === 'number') ? idx.points : null;
// Lock days (optional)
const lock = (typeof idx.lock_days === 'number') ? idx.lock_days : null;
// APY: prefer explicit idx.apy else demo from pool totals
let apy = (typeof idx.apy === 'number') ? idx.apy : null;
if (apy == null && typeof pool.total_earned === 'number' && typeof pool.total_staked === 'number' && pool.total_staked > 0){
apy = (pool.total_earned / pool.total_staked) * 100; // lifetime demo %
}
// Paint values
const setOrHide = (id, val, fmt=(x)=>x)=> {
const el = document.getElementById(id);
const wrap = el?.closest('.gw-pill');
if (!el || !wrap) return;
if (val==null || Number.isNaN(val)) { wrap.style.display='none'; return; }
el.textContent = fmt(val);
};
setOrHide('pill-apy-val', apy, (v)=> (v>=100? v.toFixed(0): v>=10? v.toFixed(1): v.toFixed(2)) + '%');
setOrHide('pill-lock-val', lock, (v)=> v + ' days');
setOrHide('pill-points-val', pts, (v)=> v.toLocaleString('en-AU'));
// If at least one pill visible, unhide the row
const visible = [...document.querySelectorAll('#gw-pills .gw-pill')].some(p=>p.style.display!=='none');
if (visible) pills.hidden = false;
// Wire Tokenomics button to open modal (inserted by Module B)
const btn = document.getElementById('pill-tokenomics');
if (btn) btn.addEventListener('click', ()=> {
const modal = document.getElementById('gw-tokenomics-modal');
if (modal) modal.showModal();
});
})();
.gwave-pills { display:flex; flex-wrap:wrap; gap:.5rem; margin:.5rem 0 1rem; }
.gw-pill { position:relative; padding:.4rem .6rem; border-radius:999px; font:600 12px/1 system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial;
background:#0f172a; color:#dbeafe; border:1px solid rgba(148,163,184,.25); }
.gw-pill[data-variant="apy"]{ background:#052e16; color:#bbf7d0; border-color:rgba(74,222,128,.25);}
.gw-pill[data-variant="lock"]{ background:#1e1b4b; color:#e9d5ff; border-color:rgba(196,181,253,.25);}
.gw-pill[data-variant="points"]{ background:#0b1220; color:#c7d2fe;}
.gw-tip { position:absolute; z-index:50; left:50%; transform:translateX(-50%); bottom:calc(100% + 8px);
white-space:nowrap; padding:.45rem .6rem; border-radius:10px; font:500 12px/1.2 system-ui; background:#111827; color:#e5e7eb;
border:1px solid rgba(255,255,255,.08); opacity:0; pointer-events:none; transition:opacity .15s ease; }
.gw-pill:hover .gw-tip{opacity:1}
APY:
—
Demo APY from pool/index data (not financial advice)
Lock:
—
Indicative lock period for staking program
Points:
—
Cumulative participation points (demo)
(async function(){
const pills = document.getElementById('gw-pills');
// Anchor: place after #kpi-live if present; else after first h1
try {
const kpi = document.getElementById('kpi-live');
const h1 = document.querySelector('h1');
if (kpi) kpi.insertAdjacentElement('afterend', pills);
else if (h1) h1.insertAdjacentElement('afterend', pills);
} catch {}
const REL = (p)=>'data/'+p, LOCAL = (p)=>'http://127.0.0.1:5199/'+p;
const getJSON = async (p)=> {
const tryOne = (u)=>fetch(u+(u.includes('?')?'&':'?')+'_cb='+Date.now(),{cache:'no-store'})
.then(r=>r.ok?r.json():Promise.reject());
try { return await tryOne(REL(p)); } catch { try { return await tryOne(LOCAL(p)); } catch { return null; } }
};
const pool = await getJSON('pool.json') || {};
const idx = await getJSON('index.json') || {};
// Points (from index.json if available)
const pts = (typeof idx.points === 'number') ? idx.points : null;
// Lock days (optional)
const lock = (typeof idx.lock_days === 'number') ? idx.lock_days : null;
// APY: prefer explicit idx.apy else demo from pool totals
let apy = (typeof idx.apy === 'number') ? idx.apy : null;
if (apy == null && typeof pool.total_earned === 'number' && typeof pool.total_staked === 'number' && pool.total_staked > 0){
apy = (pool.total_earned / pool.total_staked) * 100; // lifetime demo %
}
// Paint values
const setOrHide = (id, val, fmt=(x)=>x)=> {
const el = document.getElementById(id);
const wrap = el?.closest('.gw-pill');
if (!el || !wrap) return;
if (val==null || Number.isNaN(val)) { wrap.style.display='none'; return; }
el.textContent = fmt(val);
};
setOrHide('pill-apy-val', apy, (v)=> (v>=100? v.toFixed(0): v>=10? v.toFixed(1): v.toFixed(2)) + '%');
setOrHide('pill-lock-val', lock, (v)=> v + ' days');
setOrHide('pill-points-val', pts, (v)=> v.toLocaleString('en-AU'));
// If at least one pill visible, unhide the row
const visible = [...document.querySelectorAll('#gw-pills .gw-pill')].some(p=>p.style.display!=='none');
if (visible) pills.hidden = false;
// Wire Tokenomics button to open modal (inserted by Module B)
const btn = document.getElementById('pill-tokenomics');
if (btn) btn.addEventListener('click', ()=> {
const modal = document.getElementById('gw-tokenomics-modal');
if (modal) modal.showModal();
});
})();
.gwave-pills { display:flex; flex-wrap:wrap; gap:.5rem; margin:.5rem 0 1rem; }
.gw-pill { position:relative; padding:.4rem .6rem; border-radius:999px; font:600 12px/1 system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial;
background:#0f172a; color:#dbeafe; border:1px solid rgba(148,163,184,.25); }
.gw-pill[data-variant="apy"]{ background:#052e16; color:#bbf7d0; border-color:rgba(74,222,128,.25);}
.gw-pill[data-variant="lock"]{ background:#1e1b4b; color:#e9d5ff; border-color:rgba(196,181,253,.25);}
.gw-pill[data-variant="points"]{ background:#0b1220; color:#c7d2fe;}
.gw-tip { position:absolute; z-index:50; left:50%; transform:translateX(-50%); bottom:calc(100% + 8px);
white-space:nowrap; padding:.45rem .6rem; border-radius:10px; font:500 12px/1.2 system-ui; background:#111827; color:#e5e7eb;
border:1px solid rgba(255,255,255,.08); opacity:0; pointer-events:none; transition:opacity .15s ease; }
.gw-pill:hover .gw-tip{opacity:1}
APY:
—
Demo APY from pool/index data (not financial advice)
Lock:
—
Indicative lock period for staking program
Points:
—
Cumulative participation points (demo)
(async function(){
const pills = document.getElementById('gw-pills');
// Anchor: place after #kpi-live if present; else after first h1
try {
const kpi = document.getElementById('kpi-live');
const h1 = document.querySelector('h1');
if (kpi) kpi.insertAdjacentElement('afterend', pills);
else if (h1) h1.insertAdjacentElement('afterend', pills);
} catch {}
const REL = (p)=>'data/'+p, LOCAL = (p)=>'http://127.0.0.1:5199/'+p;
const getJSON = async (p)=> {
const tryOne = (u)=>fetch(u+(u.includes('?')?'&':'?')+'_cb='+Date.now(),{cache:'no-store'})
.then(r=>r.ok?r.json():Promise.reject());
try { return await tryOne(REL(p)); } catch { try { return await tryOne(LOCAL(p)); } catch { return null; } }
};
const pool = await getJSON('pool.json') || {};
const idx = await getJSON('index.json') || {};
// Points (from index.json if available)
const pts = (typeof idx.points === 'number') ? idx.points : null;
// Lock days (optional)
const lock = (typeof idx.lock_days === 'number') ? idx.lock_days : null;
// APY: prefer explicit idx.apy else demo from pool totals
let apy = (typeof idx.apy === 'number') ? idx.apy : null;
if (apy == null && typeof pool.total_earned === 'number' && typeof pool.total_staked === 'number' && pool.total_staked > 0){
apy = (pool.total_earned / pool.total_staked) * 100; // lifetime demo %
}
// Paint values
const setOrHide = (id, val, fmt=(x)=>x)=> {
const el = document.getElementById(id);
const wrap = el?.closest('.gw-pill');
if (!el || !wrap) return;
if (val==null || Number.isNaN(val)) { wrap.style.display='none'; return; }
el.textContent = fmt(val);
};
setOrHide('pill-apy-val', apy, (v)=> (v>=100? v.toFixed(0): v>=10? v.toFixed(1): v.toFixed(2)) + '%');
setOrHide('pill-lock-val', lock, (v)=> v + ' days');
setOrHide('pill-points-val', pts, (v)=> v.toLocaleString('en-AU'));
// If at least one pill visible, unhide the row
const visible = [...document.querySelectorAll('#gw-pills .gw-pill')].some(p=>p.style.display!=='none');
if (visible) pills.hidden = false;
// Wire Tokenomics button to open modal (inserted by Module B)
const btn = document.getElementById('pill-tokenomics');
if (btn) btn.addEventListener('click', ()=> {
const modal = document.getElementById('gw-tokenomics-modal');
if (modal) modal.showModal();
});
})();
.gwave-pills { display:flex; flex-wrap:wrap; gap:.5rem; margin:.5rem 0 1rem; }
.gw-pill { position:relative; padding:.4rem .6rem; border-radius:999px; font:600 12px/1 system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial;
background:#0f172a; color:#dbeafe; border:1px solid rgba(148,163,184,.25); }
.gw-pill[data-variant="apy"]{ background:#052e16; color:#bbf7d0; border-color:rgba(74,222,128,.25);}
.gw-pill[data-variant="lock"]{ background:#1e1b4b; color:#e9d5ff; border-color:rgba(196,181,253,.25);}
.gw-pill[data-variant="points"]{ background:#0b1220; color:#c7d2fe;}
.gw-tip { position:absolute; z-index:50; left:50%; transform:translateX(-50%); bottom:calc(100% + 8px);
white-space:nowrap; padding:.45rem .6rem; border-radius:10px; font:500 12px/1.2 system-ui; background:#111827; color:#e5e7eb;
border:1px solid rgba(255,255,255,.08); opacity:0; pointer-events:none; transition:opacity .15s ease; }
.gw-pill:hover .gw-tip{opacity:1}
APY:
—
Demo APY from pool/index data (not financial advice)
Lock:
—
Indicative lock period for staking program
Points:
—
Cumulative participation points (demo)
(async function(){
const pills = document.getElementById('gw-pills');
// Anchor: place after #kpi-live if present; else after first h1
try {
const kpi = document.getElementById('kpi-live');
const h1 = document.querySelector('h1');
if (kpi) kpi.insertAdjacentElement('afterend', pills);
else if (h1) h1.insertAdjacentElement('afterend', pills);
} catch {}
const REL = (p)=>'data/'+p, LOCAL = (p)=>'http://127.0.0.1:5199/'+p;
const getJSON = async (p)=> {
const tryOne = (u)=>fetch(u+(u.includes('?')?'&':'?')+'_cb='+Date.now(),{cache:'no-store'})
.then(r=>r.ok?r.json():Promise.reject());
try { return await tryOne(REL(p)); } catch { try { return await tryOne(LOCAL(p)); } catch { return null; } }
};
const pool = await getJSON('pool.json') || {};
const idx = await getJSON('index.json') || {};
// Points (from index.json if available)
const pts = (typeof idx.points === 'number') ? idx.points : null;
// Lock days (optional)
const lock = (typeof idx.lock_days === 'number') ? idx.lock_days : null;
// APY: prefer explicit idx.apy else demo from pool totals
let apy = (typeof idx.apy === 'number') ? idx.apy : null;
if (apy == null && typeof pool.total_earned === 'number' && typeof pool.total_staked === 'number' && pool.total_staked > 0){
apy = (pool.total_earned / pool.total_staked) * 100; // lifetime demo %
}
// Paint values
const setOrHide = (id, val, fmt=(x)=>x)=> {
const el = document.getElementById(id);
const wrap = el?.closest('.gw-pill');
if (!el || !wrap) return;
if (val==null || Number.isNaN(val)) { wrap.style.display='none'; return; }
el.textContent = fmt(val);
};
setOrHide('pill-apy-val', apy, (v)=> (v>=100? v.toFixed(0): v>=10? v.toFixed(1): v.toFixed(2)) + '%');
setOrHide('pill-lock-val', lock, (v)=> v + ' days');
setOrHide('pill-points-val', pts, (v)=> v.toLocaleString('en-AU'));
// If at least one pill visible, unhide the row
const visible = [...document.querySelectorAll('#gw-pills .gw-pill')].some(p=>p.style.display!=='none');
if (visible) pills.hidden = false;
// Wire Tokenomics button to open modal (inserted by Module B)
const btn = document.getElementById('pill-tokenomics');
if (btn) btn.addEventListener('click', ()=> {
const modal = document.getElementById('gw-tokenomics-modal');
if (modal) modal.showModal();
});
})();
LIVE • waiting for data…
.gwave-pills { display:flex; flex-wrap:wrap; gap:.5rem; margin:.5rem 0 1rem; }
.gw-pill { position:relative; padding:.4rem .6rem; border-radius:999px; font:600 12px/1 system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial;
background:#0f172a; color:#dbeafe; border:1px solid rgba(148,163,184,.25); }
.gw-pill[data-variant="apy"]{ background:#052e16; color:#bbf7d0; border-color:rgba(74,222,128,.25);}
.gw-pill[data-variant="lock"]{ background:#1e1b4b; color:#e9d5ff; border-color:rgba(196,181,253,.25);}
.gw-pill[data-variant="points"]{ background:#0b1220; color:#c7d2fe;}
.gw-tip { position:absolute; z-index:50; left:50%; transform:translateX(-50%); bottom:calc(100% + 8px);
white-space:nowrap; padding:.45rem .6rem; border-radius:10px; font:500 12px/1.2 system-ui; background:#111827; color:#e5e7eb;
border:1px solid rgba(255,255,255,.08); opacity:0; pointer-events:none; transition:opacity .15s ease; }
.gw-pill:hover .gw-tip{opacity:1}
APY:
—
Demo APY from pool/index data (not financial advice)
Lock:
—
Indicative lock period for staking program
Points:
—
Cumulative participation points (demo)
(async function(){
const pills = document.getElementById('gw-pills');
// Anchor: place after #kpi-live if present; else after first h1
try {
const kpi = document.getElementById('kpi-live');
const h1 = document.querySelector('h1');
if (kpi) kpi.insertAdjacentElement('afterend', pills);
else if (h1) h1.insertAdjacentElement('afterend', pills);
} catch {}
const REL = (p)=>'data/'+p, LOCAL = (p)=>'http://127.0.0.1:5199/'+p;
const getJSON = async (p)=> {
const tryOne = (u)=>fetch(u+(u.includes('?')?'&':'?')+'_cb='+Date.now(),{cache:'no-store'})
.then(r=>r.ok?r.json():Promise.reject());
try { return await tryOne(REL(p)); } catch { try { return await tryOne(LOCAL(p)); } catch { return null; } }
};
const pool = await getJSON('pool.json') || {};
const idx = await getJSON('index.json') || {};
// Points (from index.json if available)
const pts = (typeof idx.points === 'number') ? idx.points : null;
// Lock days (optional)
const lock = (typeof idx.lock_days === 'number') ? idx.lock_days : null;
// APY: prefer explicit idx.apy else demo from pool totals
let apy = (typeof idx.apy === 'number') ? idx.apy : null;
if (apy == null && typeof pool.total_earned === 'number' && typeof pool.total_staked === 'number' && pool.total_staked > 0){
apy = (pool.total_earned / pool.total_staked) * 100; // lifetime demo %
}
// Paint values
const setOrHide = (id, val, fmt=(x)=>x)=> {
const el = document.getElementById(id);
const wrap = el?.closest('.gw-pill');
if (!el || !wrap) return;
if (val==null || Number.isNaN(val)) { wrap.style.display='none'; return; }
el.textContent = fmt(val);
};
setOrHide('pill-apy-val', apy, (v)=> (v>=100? v.toFixed(0): v>=10? v.toFixed(1): v.toFixed(2)) + '%');
setOrHide('pill-lock-val', lock, (v)=> v + ' days');
setOrHide('pill-points-val', pts, (v)=> v.toLocaleString('en-AU'));
// If at least one pill visible, unhide the row
const visible = [...document.querySelectorAll('#gw-pills .gw-pill')].some(p=>p.style.display!=='none');
if (visible) pills.hidden = false;
// Wire Tokenomics button to open modal (inserted by Module B)
const btn = document.getElementById('pill-tokenomics');
if (btn) btn.addEventListener('click', ()=> {
const modal = document.getElementById('gw-tokenomics-modal');
if (modal) modal.showModal();
});
})();
.gwave-pills { display:flex; flex-wrap:wrap; gap:.5rem; margin:.5rem 0 1rem; }
.gw-pill { position:relative; padding:.4rem .6rem; border-radius:999px; font:600 12px/1 system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial;
background:#0f172a; color:#dbeafe; border:1px solid rgba(148,163,184,.25); }
.gw-pill[data-variant="apy"]{ background:#052e16; color:#bbf7d0; border-color:rgba(74,222,128,.25);}
.gw-pill[data-variant="lock"]{ background:#1e1b4b; color:#e9d5ff; border-color:rgba(196,181,253,.25);}
.gw-pill[data-variant="points"]{ background:#0b1220; color:#c7d2fe;}
.gw-tip { position:absolute; z-index:50; left:50%; transform:translateX(-50%); bottom:calc(100% + 8px);
white-space:nowrap; padding:.45rem .6rem; border-radius:10px; font:500 12px/1.2 system-ui; background:#111827; color:#e5e7eb;
border:1px solid rgba(255,255,255,.08); opacity:0; pointer-events:none; transition:opacity .15s ease; }
.gw-pill:hover .gw-tip{opacity:1}
APY:
—
Demo APY from pool/index data (not financial advice)
Lock:
—
Indicative lock period for staking program
Points:
—
Cumulative participation points (demo)
(async function(){
const pills = document.getElementById('gw-pills');
// Anchor: place after #kpi-live if present; else after first h1
try {
const kpi = document.getElementById('kpi-live');
const h1 = document.querySelector('h1');
if (kpi) kpi.insertAdjacentElement('afterend', pills);
else if (h1) h1.insertAdjacentElement('afterend', pills);
} catch {}
const REL = (p)=>'data/'+p, LOCAL = (p)=>'http://127.0.0.1:5199/'+p;
const getJSON = async (p)=> {
const tryOne = (u)=>fetch(u+(u.includes('?')?'&':'?')+'_cb='+Date.now(),{cache:'no-store'})
.then(r=>r.ok?r.json():Promise.reject());
try { return await tryOne(REL(p)); } catch { try { return await tryOne(LOCAL(p)); } catch { return null; } }
};
const pool = await getJSON('pool.json') || {};
const idx = await getJSON('index.json') || {};
// Points (from index.json if available)
const pts = (typeof idx.points === 'number') ? idx.points : null;
// Lock days (optional)
const lock = (typeof idx.lock_days === 'number') ? idx.lock_days : null;
// APY: prefer explicit idx.apy else demo from pool totals
let apy = (typeof idx.apy === 'number') ? idx.apy : null;
if (apy == null && typeof pool.total_earned === 'number' && typeof pool.total_staked === 'number' && pool.total_staked > 0){
apy = (pool.total_earned / pool.total_staked) * 100; // lifetime demo %
}
// Paint values
const setOrHide = (id, val, fmt=(x)=>x)=> {
const el = document.getElementById(id);
const wrap = el?.closest('.gw-pill');
if (!el || !wrap) return;
if (val==null || Number.isNaN(val)) { wrap.style.display='none'; return; }
el.textContent = fmt(val);
};
setOrHide('pill-apy-val', apy, (v)=> (v>=100? v.toFixed(0): v>=10? v.toFixed(1): v.toFixed(2)) + '%');
setOrHide('pill-lock-val', lock, (v)=> v + ' days');
setOrHide('pill-points-val', pts, (v)=> v.toLocaleString('en-AU'));
// If at least one pill visible, unhide the row
const visible = [...document.querySelectorAll('#gw-pills .gw-pill')].some(p=>p.style.display!=='none');
if (visible) pills.hidden = false;
// Wire Tokenomics button to open modal (inserted by Module B)
const btn = document.getElementById('pill-tokenomics');
if (btn) btn.addEventListener('click', ()=> {
const modal = document.getElementById('gw-tokenomics-modal');
if (modal) modal.showModal();
});
})();
.gwave-pills { display:flex; flex-wrap:wrap; gap:.5rem; margin:.5rem 0 1rem; }
.gw-pill { position:relative; padding:.4rem .6rem; border-radius:999px; font:600 12px/1 system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial;
background:#0f172a; color:#dbeafe; border:1px solid rgba(148,163,184,.25); }
.gw-pill[data-variant="apy"]{ background:#052e16; color:#bbf7d0; border-color:rgba(74,222,128,.25);}
.gw-pill[data-variant="lock"]{ background:#1e1b4b; color:#e9d5ff; border-color:rgba(196,181,253,.25);}
.gw-pill[data-variant="points"]{ background:#0b1220; color:#c7d2fe;}
.gw-tip { position:absolute; z-index:50; left:50%; transform:translateX(-50%); bottom:calc(100% + 8px);
white-space:nowrap; padding:.45rem .6rem; border-radius:10px; font:500 12px/1.2 system-ui; background:#111827; color:#e5e7eb;
border:1px solid rgba(255,255,255,.08); opacity:0; pointer-events:none; transition:opacity .15s ease; }
.gw-pill:hover .gw-tip{opacity:1}
APY:
—
Demo APY from pool/index data (not financial advice)
Lock:
—
Indicative lock period for staking program
Points:
—
Cumulative participation points (demo)
(async function(){
const pills = document.getElementById('gw-pills');
// Anchor: place after #kpi-live if present; else after first h1
try {
const kpi = document.getElementById('kpi-live');
const h1 = document.querySelector('h1');
if (kpi) kpi.insertAdjacentElement('afterend', pills);
else if (h1) h1.insertAdjacentElement('afterend', pills);
} catch {}
const REL = (p)=>'data/'+p, LOCAL = (p)=>'http://127.0.0.1:5199/'+p;
const getJSON = async (p)=> {
const tryOne = (u)=>fetch(u+(u.includes('?')?'&':'?')+'_cb='+Date.now(),{cache:'no-store'})
.then(r=>r.ok?r.json():Promise.reject());
try { return await tryOne(REL(p)); } catch { try { return await tryOne(LOCAL(p)); } catch { return null; } }
};
const pool = await getJSON('pool.json') || {};
const idx = await getJSON('index.json') || {};
// Points (from index.json if available)
const pts = (typeof idx.points === 'number') ? idx.points : null;
// Lock days (optional)
const lock = (typeof idx.lock_days === 'number') ? idx.lock_days : null;
// APY: prefer explicit idx.apy else demo from pool totals
let apy = (typeof idx.apy === 'number') ? idx.apy : null;
if (apy == null && typeof pool.total_earned === 'number' && typeof pool.total_staked === 'number' && pool.total_staked > 0){
apy = (pool.total_earned / pool.total_staked) * 100; // lifetime demo %
}
// Paint values
const setOrHide = (id, val, fmt=(x)=>x)=> {
const el = document.getElementById(id);
const wrap = el?.closest('.gw-pill');
if (!el || !wrap) return;
if (val==null || Number.isNaN(val)) { wrap.style.display='none'; return; }
el.textContent = fmt(val);
};
setOrHide('pill-apy-val', apy, (v)=> (v>=100? v.toFixed(0): v>=10? v.toFixed(1): v.toFixed(2)) + '%');
setOrHide('pill-lock-val', lock, (v)=> v + ' days');
setOrHide('pill-points-val', pts, (v)=> v.toLocaleString('en-AU'));
// If at least one pill visible, unhide the row
const visible = [...document.querySelectorAll('#gw-pills .gw-pill')].some(p=>p.style.display!=='none');
if (visible) pills.hidden = false;
// Wire Tokenomics button to open modal (inserted by Module B)
const btn = document.getElementById('pill-tokenomics');
if (btn) btn.addEventListener('click', ()=> {
const modal = document.getElementById('gw-tokenomics-modal');
if (modal) modal.showModal();
});
})();
.gwave-pills { display:flex; flex-wrap:wrap; gap:.5rem; margin:.5rem 0 1rem; }
.gw-pill { position:relative; padding:.4rem .6rem; border-radius:999px; font:600 12px/1 system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial;
background:#0f172a; color:#dbeafe; border:1px solid rgba(148,163,184,.25); }
.gw-pill[data-variant="apy"]{ background:#052e16; color:#bbf7d0; border-color:rgba(74,222,128,.25);}
.gw-pill[data-variant="lock"]{ background:#1e1b4b; color:#e9d5ff; border-color:rgba(196,181,253,.25);}
.gw-pill[data-variant="points"]{ background:#0b1220; color:#c7d2fe;}
.gw-tip { position:absolute; z-index:50; left:50%; transform:translateX(-50%); bottom:calc(100% + 8px);
white-space:nowrap; padding:.45rem .6rem; border-radius:10px; font:500 12px/1.2 system-ui; background:#111827; color:#e5e7eb;
border:1px solid rgba(255,255,255,.08); opacity:0; pointer-events:none; transition:opacity .15s ease; }
.gw-pill:hover .gw-tip{opacity:1}
APY:
—
Demo APY from pool/index data (not financial advice)
Lock:
—
Indicative lock period for staking program
Points:
—
Cumulative participation points (demo)
(async function(){
const pills = document.getElementById('gw-pills');
// Anchor: place after #kpi-live if present; else after first h1
try {
const kpi = document.getElementById('kpi-live');
const h1 = document.querySelector('h1');
if (kpi) kpi.insertAdjacentElement('afterend', pills);
else if (h1) h1.insertAdjacentElement('afterend', pills);
} catch {}
const REL = (p)=>'data/'+p, LOCAL = (p)=>'http://127.0.0.1:5199/'+p;
const getJSON = async (p)=> {
const tryOne = (u)=>fetch(u+(u.includes('?')?'&':'?')+'_cb='+Date.now(),{cache:'no-store'})
.then(r=>r.ok?r.json():Promise.reject());
try { return await tryOne(REL(p)); } catch { try { return await tryOne(LOCAL(p)); } catch { return null; } }
};
const pool = await getJSON('pool.json') || {};
const idx = await getJSON('index.json') || {};
// Points (from index.json if available)
const pts = (typeof idx.points === 'number') ? idx.points : null;
// Lock days (optional)
const lock = (typeof idx.lock_days === 'number') ? idx.lock_days : null;
// APY: prefer explicit idx.apy else demo from pool totals
let apy = (typeof idx.apy === 'number') ? idx.apy : null;
if (apy == null && typeof pool.total_earned === 'number' && typeof pool.total_staked === 'number' && pool.total_staked > 0){
apy = (pool.total_earned / pool.total_staked) * 100; // lifetime demo %
}
// Paint values
const setOrHide = (id, val, fmt=(x)=>x)=> {
const el = document.getElementById(id);
const wrap = el?.closest('.gw-pill');
if (!el || !wrap) return;
if (val==null || Number.isNaN(val)) { wrap.style.display='none'; return; }
el.textContent = fmt(val);
};
setOrHide('pill-apy-val', apy, (v)=> (v>=100? v.toFixed(0): v>=10? v.toFixed(1): v.toFixed(2)) + '%');
setOrHide('pill-lock-val', lock, (v)=> v + ' days');
setOrHide('pill-points-val', pts, (v)=> v.toLocaleString('en-AU'));
// If at least one pill visible, unhide the row
const visible = [...document.querySelectorAll('#gw-pills .gw-pill')].some(p=>p.style.display!=='none');
if (visible) pills.hidden = false;
// Wire Tokenomics button to open modal (inserted by Module B)
const btn = document.getElementById('pill-tokenomics');
if (btn) btn.addEventListener('click', ()=> {
const modal = document.getElementById('gw-tokenomics-modal');
if (modal) modal.showModal();
});
})();
.gwave-pills { display:flex; flex-wrap:wrap; gap:.5rem; margin:.5rem 0 1rem; }
.gw-pill { position:relative; padding:.4rem .6rem; border-radius:999px; font:600 12px/1 system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial;
background:#0f172a; color:#dbeafe; border:1px solid rgba(148,163,184,.25); }
.gw-pill[data-variant="apy"]{ background:#052e16; color:#bbf7d0; border-color:rgba(74,222,128,.25);}
.gw-pill[data-variant="lock"]{ background:#1e1b4b; color:#e9d5ff; border-color:rgba(196,181,253,.25);}
.gw-pill[data-variant="points"]{ background:#0b1220; color:#c7d2fe;}
.gw-tip { position:absolute; z-index:50; left:50%; transform:translateX(-50%); bottom:calc(100% + 8px);
white-space:nowrap; padding:.45rem .6rem; border-radius:10px; font:500 12px/1.2 system-ui; background:#111827; color:#e5e7eb;
border:1px solid rgba(255,255,255,.08); opacity:0; pointer-events:none; transition:opacity .15s ease; }
.gw-pill:hover .gw-tip{opacity:1}
APY:
—
Demo APY from pool/index data (not financial advice)
Lock:
—
Indicative lock period for staking program
Points:
—
Cumulative participation points (demo)
(async function(){
const pills = document.getElementById('gw-pills');
// Anchor: place after #kpi-live if present; else after first h1
try {
const kpi = document.getElementById('kpi-live');
const h1 = document.querySelector('h1');
if (kpi) kpi.insertAdjacentElement('afterend', pills);
else if (h1) h1.insertAdjacentElement('afterend', pills);
} catch {}
const REL = (p)=>'data/'+p, LOCAL = (p)=>'http://127.0.0.1:5199/'+p;
const getJSON = async (p)=> {
const tryOne = (u)=>fetch(u+(u.includes('?')?'&':'?')+'_cb='+Date.now(),{cache:'no-store'})
.then(r=>r.ok?r.json():Promise.reject());
try { return await tryOne(REL(p)); } catch { try { return await tryOne(LOCAL(p)); } catch { return null; } }
};
const pool = await getJSON('pool.json') || {};
const idx = await getJSON('index.json') || {};
// Points (from index.json if available)
const pts = (typeof idx.points === 'number') ? idx.points : null;
// Lock days (optional)
const lock = (typeof idx.lock_days === 'number') ? idx.lock_days : null;
// APY: prefer explicit idx.apy else demo from pool totals
let apy = (typeof idx.apy === 'number') ? idx.apy : null;
if (apy == null && typeof pool.total_earned === 'number' && typeof pool.total_staked === 'number' && pool.total_staked > 0){
apy = (pool.total_earned / pool.total_staked) * 100; // lifetime demo %
}
// Paint values
const setOrHide = (id, val, fmt=(x)=>x)=> {
const el = document.getElementById(id);
const wrap = el?.closest('.gw-pill');
if (!el || !wrap) return;
if (val==null || Number.isNaN(val)) { wrap.style.display='none'; return; }
el.textContent = fmt(val);
};
setOrHide('pill-apy-val', apy, (v)=> (v>=100? v.toFixed(0): v>=10? v.toFixed(1): v.toFixed(2)) + '%');
setOrHide('pill-lock-val', lock, (v)=> v + ' days');
setOrHide('pill-points-val', pts, (v)=> v.toLocaleString('en-AU'));
// If at least one pill visible, unhide the row
const visible = [...document.querySelectorAll('#gw-pills .gw-pill')].some(p=>p.style.display!=='none');
if (visible) pills.hidden = false;
// Wire Tokenomics button to open modal (inserted by Module B)
const btn = document.getElementById('pill-tokenomics');
if (btn) btn.addEventListener('click', ()=> {
const modal = document.getElementById('gw-tokenomics-modal');
if (modal) modal.showModal();
});
})();
.gwave-pills { display:flex; flex-wrap:wrap; gap:.5rem; margin:.5rem 0 1rem; }
.gw-pill { position:relative; padding:.4rem .6rem; border-radius:999px; font:600 12px/1 system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial;
background:#0f172a; color:#dbeafe; border:1px solid rgba(148,163,184,.25); }
.gw-pill[data-variant="apy"]{ background:#052e16; color:#bbf7d0; border-color:rgba(74,222,128,.25);}
.gw-pill[data-variant="lock"]{ background:#1e1b4b; color:#e9d5ff; border-color:rgba(196,181,253,.25);}
.gw-pill[data-variant="points"]{ background:#0b1220; color:#c7d2fe;}
.gw-tip { position:absolute; z-index:50; left:50%; transform:translateX(-50%); bottom:calc(100% + 8px);
white-space:nowrap; padding:.45rem .6rem; border-radius:10px; font:500 12px/1.2 system-ui; background:#111827; color:#e5e7eb;
border:1px solid rgba(255,255,255,.08); opacity:0; pointer-events:none; transition:opacity .15s ease; }
.gw-pill:hover .gw-tip{opacity:1}
APY:
—
Demo APY from pool/index data (not financial advice)
Lock:
—
Indicative lock period for staking program
Points:
—
Cumulative participation points (demo)
(async function(){
const pills = document.getElementById('gw-pills');
// Anchor: place after #kpi-live if present; else after first h1
try {
const kpi = document.getElementById('kpi-live');
const h1 = document.querySelector('h1');
if (kpi) kpi.insertAdjacentElement('afterend', pills);
else if (h1) h1.insertAdjacentElement('afterend', pills);
} catch {}
const REL = (p)=>'data/'+p, LOCAL = (p)=>'http://127.0.0.1:5199/'+p;
const getJSON = async (p)=> {
const tryOne = (u)=>fetch(u+(u.includes('?')?'&':'?')+'_cb='+Date.now(),{cache:'no-store'})
.then(r=>r.ok?r.json():Promise.reject());
try { return await tryOne(REL(p)); } catch { try { return await tryOne(LOCAL(p)); } catch { return null; } }
};
const pool = await getJSON('pool.json') || {};
const idx = await getJSON('index.json') || {};
// Points (from index.json if available)
const pts = (typeof idx.points === 'number') ? idx.points : null;
// Lock days (optional)
const lock = (typeof idx.lock_days === 'number') ? idx.lock_days : null;
// APY: prefer explicit idx.apy else demo from pool totals
let apy = (typeof idx.apy === 'number') ? idx.apy : null;
if (apy == null && typeof pool.total_earned === 'number' && typeof pool.total_staked === 'number' && pool.total_staked > 0){
apy = (pool.total_earned / pool.total_staked) * 100; // lifetime demo %
}
// Paint values
const setOrHide = (id, val, fmt=(x)=>x)=> {
const el = document.getElementById(id);
const wrap = el?.closest('.gw-pill');
if (!el || !wrap) return;
if (val==null || Number.isNaN(val)) { wrap.style.display='none'; return; }
el.textContent = fmt(val);
};
setOrHide('pill-apy-val', apy, (v)=> (v>=100? v.toFixed(0): v>=10? v.toFixed(1): v.toFixed(2)) + '%');
setOrHide('pill-lock-val', lock, (v)=> v + ' days');
setOrHide('pill-points-val', pts, (v)=> v.toLocaleString('en-AU'));
// If at least one pill visible, unhide the row
const visible = [...document.querySelectorAll('#gw-pills .gw-pill')].some(p=>p.style.display!=='none');
if (visible) pills.hidden = false;
// Wire Tokenomics button to open modal (inserted by Module B)
const btn = document.getElementById('pill-tokenomics');
if (btn) btn.addEventListener('click', ()=> {
const modal = document.getElementById('gw-tokenomics-modal');
if (modal) modal.showModal();
});
})();
.gwave-pills { display:flex; flex-wrap:wrap; gap:.5rem; margin:.5rem 0 1rem; }
.gw-pill { position:relative; padding:.4rem .6rem; border-radius:999px; font:600 12px/1 system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial;
background:#0f172a; color:#dbeafe; border:1px solid rgba(148,163,184,.25); }
.gw-pill[data-variant="apy"]{ background:#052e16; color:#bbf7d0; border-color:rgba(74,222,128,.25);}
.gw-pill[data-variant="lock"]{ background:#1e1b4b; color:#e9d5ff; border-color:rgba(196,181,253,.25);}
.gw-pill[data-variant="points"]{ background:#0b1220; color:#c7d2fe;}
.gw-tip { position:absolute; z-index:50; left:50%; transform:translateX(-50%); bottom:calc(100% + 8px);
white-space:nowrap; padding:.45rem .6rem; border-radius:10px; font:500 12px/1.2 system-ui; background:#111827; color:#e5e7eb;
border:1px solid rgba(255,255,255,.08); opacity:0; pointer-events:none; transition:opacity .15s ease; }
.gw-pill:hover .gw-tip{opacity:1}
APY:
—
Demo APY from pool/index data (not financial advice)
Lock:
—
Indicative lock period for staking program
Points:
—
Cumulative participation points (demo)
(async function(){
const pills = document.getElementById('gw-pills');
// Anchor: place after #kpi-live if present; else after first h1
try {
const kpi = document.getElementById('kpi-live');
const h1 = document.querySelector('h1');
if (kpi) kpi.insertAdjacentElement('afterend', pills);
else if (h1) h1.insertAdjacentElement('afterend', pills);
} catch {}
const REL = (p)=>'data/'+p, LOCAL = (p)=>'http://127.0.0.1:5199/'+p;
const getJSON = async (p)=> {
const tryOne = (u)=>fetch(u+(u.includes('?')?'&':'?')+'_cb='+Date.now(),{cache:'no-store'})
.then(r=>r.ok?r.json():Promise.reject());
try { return await tryOne(REL(p)); } catch { try { return await tryOne(LOCAL(p)); } catch { return null; } }
};
const pool = await getJSON('pool.json') || {};
const idx = await getJSON('index.json') || {};
// Points (from index.json if available)
const pts = (typeof idx.points === 'number') ? idx.points : null;
// Lock days (optional)
const lock = (typeof idx.lock_days === 'number') ? idx.lock_days : null;
// APY: prefer explicit idx.apy else demo from pool totals
let apy = (typeof idx.apy === 'number') ? idx.apy : null;
if (apy == null && typeof pool.total_earned === 'number' && typeof pool.total_staked === 'number' && pool.total_staked > 0){
apy = (pool.total_earned / pool.total_staked) * 100; // lifetime demo %
}
// Paint values
const setOrHide = (id, val, fmt=(x)=>x)=> {
const el = document.getElementById(id);
const wrap = el?.closest('.gw-pill');
if (!el || !wrap) return;
if (val==null || Number.isNaN(val)) { wrap.style.display='none'; return; }
el.textContent = fmt(val);
};
setOrHide('pill-apy-val', apy, (v)=> (v>=100? v.toFixed(0): v>=10? v.toFixed(1): v.toFixed(2)) + '%');
setOrHide('pill-lock-val', lock, (v)=> v + ' days');
setOrHide('pill-points-val', pts, (v)=> v.toLocaleString('en-AU'));
// If at least one pill visible, unhide the row
const visible = [...document.querySelectorAll('#gw-pills .gw-pill')].some(p=>p.style.display!=='none');
if (visible) pills.hidden = false;
// Wire Tokenomics button to open modal (inserted by Module B)
const btn = document.getElementById('pill-tokenomics');
if (btn) btn.addEventListener('click', ()=> {
const modal = document.getElementById('gw-tokenomics-modal');
if (modal) modal.showModal();
});
})();
.gwave-pills { display:flex; flex-wrap:wrap; gap:.5rem; margin:.5rem 0 1rem; }
.gw-pill { position:relative; padding:.4rem .6rem; border-radius:999px; font:600 12px/1 system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial;
background:#0f172a; color:#dbeafe; border:1px solid rgba(148,163,184,.25); }
.gw-pill[data-variant="apy"]{ background:#052e16; color:#bbf7d0; border-color:rgba(74,222,128,.25);}
.gw-pill[data-variant="lock"]{ background:#1e1b4b; color:#e9d5ff; border-color:rgba(196,181,253,.25);}
.gw-pill[data-variant="points"]{ background:#0b1220; color:#c7d2fe;}
.gw-tip { position:absolute; z-index:50; left:50%; transform:translateX(-50%); bottom:calc(100% + 8px);
white-space:nowrap; padding:.45rem .6rem; border-radius:10px; font:500 12px/1.2 system-ui; background:#111827; color:#e5e7eb;
border:1px solid rgba(255,255,255,.08); opacity:0; pointer-events:none; transition:opacity .15s ease; }
.gw-pill:hover .gw-tip{opacity:1}
APY:
—
Demo APY from pool/index data (not financial advice)
Lock:
—
Indicative lock period for staking program
Points:
—
Cumulative participation points (demo)
(async function(){
const pills = document.getElementById('gw-pills');
// Anchor: place after #kpi-live if present; else after first h1
try {
const kpi = document.getElementById('kpi-live');
const h1 = document.querySelector('h1');
if (kpi) kpi.insertAdjacentElement('afterend', pills);
else if (h1) h1.insertAdjacentElement('afterend', pills);
} catch {}
const REL = (p)=>'data/'+p, LOCAL = (p)=>'http://127.0.0.1:5199/'+p;
const getJSON = async (p)=> {
const tryOne = (u)=>fetch(u+(u.includes('?')?'&':'?')+'_cb='+Date.now(),{cache:'no-store'})
.then(r=>r.ok?r.json():Promise.reject());
try { return await tryOne(REL(p)); } catch { try { return await tryOne(LOCAL(p)); } catch { return null; } }
};
const pool = await getJSON('pool.json') || {};
const idx = await getJSON('index.json') || {};
// Points (from index.json if available)
const pts = (typeof idx.points === 'number') ? idx.points : null;
// Lock days (optional)
const lock = (typeof idx.lock_days === 'number') ? idx.lock_days : null;
// APY: prefer explicit idx.apy else demo from pool totals
let apy = (typeof idx.apy === 'number') ? idx.apy : null;
if (apy == null && typeof pool.total_earned === 'number' && typeof pool.total_staked === 'number' && pool.total_staked > 0){
apy = (pool.total_earned / pool.total_staked) * 100; // lifetime demo %
}
// Paint values
const setOrHide = (id, val, fmt=(x)=>x)=> {
const el = document.getElementById(id);
const wrap = el?.closest('.gw-pill');
if (!el || !wrap) return;
if (val==null || Number.isNaN(val)) { wrap.style.display='none'; return; }
el.textContent = fmt(val);
};
setOrHide('pill-apy-val', apy, (v)=> (v>=100? v.toFixed(0): v>=10? v.toFixed(1): v.toFixed(2)) + '%');
setOrHide('pill-lock-val', lock, (v)=> v + ' days');
setOrHide('pill-points-val', pts, (v)=> v.toLocaleString('en-AU'));
// If at least one pill visible, unhide the row
const visible = [...document.querySelectorAll('#gw-pills .gw-pill')].some(p=>p.style.display!=='none');
if (visible) pills.hidden = false;
// Wire Tokenomics button to open modal (inserted by Module B)
const btn = document.getElementById('pill-tokenomics');
if (btn) btn.addEventListener('click', ()=> {
const modal = document.getElementById('gw-tokenomics-modal');
if (modal) modal.showModal();
});
})();
.gwave-pills { display:flex; flex-wrap:wrap; gap:.5rem; margin:.5rem 0 1rem; }
.gw-pill { position:relative; padding:.4rem .6rem; border-radius:999px; font:600 12px/1 system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial;
background:#0f172a; color:#dbeafe; border:1px solid rgba(148,163,184,.25); }
.gw-pill[data-variant="apy"]{ background:#052e16; color:#bbf7d0; border-color:rgba(74,222,128,.25);}
.gw-pill[data-variant="lock"]{ background:#1e1b4b; color:#e9d5ff; border-color:rgba(196,181,253,.25);}
.gw-pill[data-variant="points"]{ background:#0b1220; color:#c7d2fe;}
.gw-tip { position:absolute; z-index:50; left:50%; transform:translateX(-50%); bottom:calc(100% + 8px);
white-space:nowrap; padding:.45rem .6rem; border-radius:10px; font:500 12px/1.2 system-ui; background:#111827; color:#e5e7eb;
border:1px solid rgba(255,255,255,.08); opacity:0; pointer-events:none; transition:opacity .15s ease; }
.gw-pill:hover .gw-tip{opacity:1}
APY:
—
Demo APY from pool/index data (not financial advice)
Lock:
—
Indicative lock period for staking program
Points:
—
Cumulative participation points (demo)
(async function(){
const pills = document.getElementById('gw-pills');
// Anchor: place after #kpi-live if present; else after first h1
try {
const kpi = document.getElementById('kpi-live');
const h1 = document.querySelector('h1');
if (kpi) kpi.insertAdjacentElement('afterend', pills);
else if (h1) h1.insertAdjacentElement('afterend', pills);
} catch {}
const REL = (p)=>'data/'+p, LOCAL = (p)=>'http://127.0.0.1:5199/'+p;
const getJSON = async (p)=> {
const tryOne = (u)=>fetch(u+(u.includes('?')?'&':'?')+'_cb='+Date.now(),{cache:'no-store'})
.then(r=>r.ok?r.json():Promise.reject());
try { return await tryOne(REL(p)); } catch { try { return await tryOne(LOCAL(p)); } catch { return null; } }
};
const pool = await getJSON('pool.json') || {};
const idx = await getJSON('index.json') || {};
// Points (from index.json if available)
const pts = (typeof idx.points === 'number') ? idx.points : null;
// Lock days (optional)
const lock = (typeof idx.lock_days === 'number') ? idx.lock_days : null;
// APY: prefer explicit idx.apy else demo from pool totals
let apy = (typeof idx.apy === 'number') ? idx.apy : null;
if (apy == null && typeof pool.total_earned === 'number' && typeof pool.total_staked === 'number' && pool.total_staked > 0){
apy = (pool.total_earned / pool.total_staked) * 100; // lifetime demo %
}
// Paint values
const setOrHide = (id, val, fmt=(x)=>x)=> {
const el = document.getElementById(id);
const wrap = el?.closest('.gw-pill');
if (!el || !wrap) return;
if (val==null || Number.isNaN(val)) { wrap.style.display='none'; return; }
el.textContent = fmt(val);
};
setOrHide('pill-apy-val', apy, (v)=> (v>=100? v.toFixed(0): v>=10? v.toFixed(1): v.toFixed(2)) + '%');
setOrHide('pill-lock-val', lock, (v)=> v + ' days');
setOrHide('pill-points-val', pts, (v)=> v.toLocaleString('en-AU'));
// If at least one pill visible, unhide the row
const visible = [...document.querySelectorAll('#gw-pills .gw-pill')].some(p=>p.style.display!=='none');
if (visible) pills.hidden = false;
// Wire Tokenomics button to open modal (inserted by Module B)
const btn = document.getElementById('pill-tokenomics');
if (btn) btn.addEventListener('click', ()=> {
const modal = document.getElementById('gw-tokenomics-modal');
if (modal) modal.showModal();
});
})();
.gwave-pills { display:flex; flex-wrap:wrap; gap:.5rem; margin:.5rem 0 1rem; }
.gw-pill { position:relative; padding:.4rem .6rem; border-radius:999px; font:600 12px/1 system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial;
background:#0f172a; color:#dbeafe; border:1px solid rgba(148,163,184,.25); }
.gw-pill[data-variant="apy"]{ background:#052e16; color:#bbf7d0; border-color:rgba(74,222,128,.25);}
.gw-pill[data-variant="lock"]{ background:#1e1b4b; color:#e9d5ff; border-color:rgba(196,181,253,.25);}
.gw-pill[data-variant="points"]{ background:#0b1220; color:#c7d2fe;}
.gw-tip { position:absolute; z-index:50; left:50%; transform:translateX(-50%); bottom:calc(100% + 8px);
white-space:nowrap; padding:.45rem .6rem; border-radius:10px; font:500 12px/1.2 system-ui; background:#111827; color:#e5e7eb;
border:1px solid rgba(255,255,255,.08); opacity:0; pointer-events:none; transition:opacity .15s ease; }
.gw-pill:hover .gw-tip{opacity:1}
APY:
—
Demo APY from pool/index data (not financial advice)
Lock:
—
Indicative lock period for staking program
Points:
—
Cumulative participation points (demo)
(async function(){
const pills = document.getElementById('gw-pills');
// Anchor: place after #kpi-live if present; else after first h1
try {
const kpi = document.getElementById('kpi-live');
const h1 = document.querySelector('h1');
if (kpi) kpi.insertAdjacentElement('afterend', pills);
else if (h1) h1.insertAdjacentElement('afterend', pills);
} catch {}
const REL = (p)=>'data/'+p, LOCAL = (p)=>'http://127.0.0.1:5199/'+p;
const getJSON = async (p)=> {
const tryOne = (u)=>fetch(u+(u.includes('?')?'&':'?')+'_cb='+Date.now(),{cache:'no-store'})
.then(r=>r.ok?r.json():Promise.reject());
try { return await tryOne(REL(p)); } catch { try { return await tryOne(LOCAL(p)); } catch { return null; } }
};
const pool = await getJSON('pool.json') || {};
const idx = await getJSON('index.json') || {};
// Points (from index.json if available)
const pts = (typeof idx.points === 'number') ? idx.points : null;
// Lock days (optional)
const lock = (typeof idx.lock_days === 'number') ? idx.lock_days : null;
// APY: prefer explicit idx.apy else demo from pool totals
let apy = (typeof idx.apy === 'number') ? idx.apy : null;
if (apy == null && typeof pool.total_earned === 'number' && typeof pool.total_staked === 'number' && pool.total_staked > 0){
apy = (pool.total_earned / pool.total_staked) * 100; // lifetime demo %
}
// Paint values
const setOrHide = (id, val, fmt=(x)=>x)=> {
const el = document.getElementById(id);
const wrap = el?.closest('.gw-pill');
if (!el || !wrap) return;
if (val==null || Number.isNaN(val)) { wrap.style.display='none'; return; }
el.textContent = fmt(val);
};
setOrHide('pill-apy-val', apy, (v)=> (v>=100? v.toFixed(0): v>=10? v.toFixed(1): v.toFixed(2)) + '%');
setOrHide('pill-lock-val', lock, (v)=> v + ' days');
setOrHide('pill-points-val', pts, (v)=> v.toLocaleString('en-AU'));
// If at least one pill visible, unhide the row
const visible = [...document.querySelectorAll('#gw-pills .gw-pill')].some(p=>p.style.display!=='none');
if (visible) pills.hidden = false;
// Wire Tokenomics button to open modal (inserted by Module B)
const btn = document.getElementById('pill-tokenomics');
if (btn) btn.addEventListener('click', ()=> {
const modal = document.getElementById('gw-tokenomics-modal');
if (modal) modal.showModal();
});
})();
.gwave-pills { display:flex; flex-wrap:wrap; gap:.5rem; margin:.5rem 0 1rem; }
.gw-pill { position:relative; padding:.4rem .6rem; border-radius:999px; font:600 12px/1 system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial;
background:#0f172a; color:#dbeafe; border:1px solid rgba(148,163,184,.25); }
.gw-pill[data-variant="apy"]{ background:#052e16; color:#bbf7d0; border-color:rgba(74,222,128,.25);}
.gw-pill[data-variant="lock"]{ background:#1e1b4b; color:#e9d5ff; border-color:rgba(196,181,253,.25);}
.gw-pill[data-variant="points"]{ background:#0b1220; color:#c7d2fe;}
.gw-tip { position:absolute; z-index:50; left:50%; transform:translateX(-50%); bottom:calc(100% + 8px);
white-space:nowrap; padding:.45rem .6rem; border-radius:10px; font:500 12px/1.2 system-ui; background:#111827; color:#e5e7eb;
border:1px solid rgba(255,255,255,.08); opacity:0; pointer-events:none; transition:opacity .15s ease; }
.gw-pill:hover .gw-tip{opacity:1}
APY:
—
Demo APY from pool/index data (not financial advice)
Lock:
—
Indicative lock period for staking program
Points:
—
Cumulative participation points (demo)
(async function(){
const pills = document.getElementById('gw-pills');
// Anchor: place after #kpi-live if present; else after first h1
try {
const kpi = document.getElementById('kpi-live');
const h1 = document.querySelector('h1');
if (kpi) kpi.insertAdjacentElement('afterend', pills);
else if (h1) h1.insertAdjacentElement('afterend', pills);
} catch {}
const REL = (p)=>'data/'+p, LOCAL = (p)=>'http://127.0.0.1:5199/'+p;
const getJSON = async (p)=> {
const tryOne = (u)=>fetch(u+(u.includes('?')?'&':'?')+'_cb='+Date.now(),{cache:'no-store'})
.then(r=>r.ok?r.json():Promise.reject());
try { return await tryOne(REL(p)); } catch { try { return await tryOne(LOCAL(p)); } catch { return null; } }
};
const pool = await getJSON('pool.json') || {};
const idx = await getJSON('index.json') || {};
// Points (from index.json if available)
const pts = (typeof idx.points === 'number') ? idx.points : null;
// Lock days (optional)
const lock = (typeof idx.lock_days === 'number') ? idx.lock_days : null;
// APY: prefer explicit idx.apy else demo from pool totals
let apy = (typeof idx.apy === 'number') ? idx.apy : null;
if (apy == null && typeof pool.total_earned === 'number' && typeof pool.total_staked === 'number' && pool.total_staked > 0){
apy = (pool.total_earned / pool.total_staked) * 100; // lifetime demo %
}
// Paint values
const setOrHide = (id, val, fmt=(x)=>x)=> {
const el = document.getElementById(id);
const wrap = el?.closest('.gw-pill');
if (!el || !wrap) return;
if (val==null || Number.isNaN(val)) { wrap.style.display='none'; return; }
el.textContent = fmt(val);
};
setOrHide('pill-apy-val', apy, (v)=> (v>=100? v.toFixed(0): v>=10? v.toFixed(1): v.toFixed(2)) + '%');
setOrHide('pill-lock-val', lock, (v)=> v + ' days');
setOrHide('pill-points-val', pts, (v)=> v.toLocaleString('en-AU'));
// If at least one pill visible, unhide the row
const visible = [...document.querySelectorAll('#gw-pills .gw-pill')].some(p=>p.style.display!=='none');
if (visible) pills.hidden = false;
// Wire Tokenomics button to open modal (inserted by Module B)
const btn = document.getElementById('pill-tokenomics');
if (btn) btn.addEventListener('click', ()=> {
const modal = document.getElementById('gw-tokenomics-modal');
if (modal) modal.showModal();
});
})();
Updates every ~60s from
docs/data/index.json and
docs/data/pool.json.
.gwave-pills { display:flex; flex-wrap:wrap; gap:.5rem; margin:.5rem 0 1rem; }
.gw-pill { position:relative; padding:.4rem .6rem; border-radius:999px; font:600 12px/1 system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial;
background:#0f172a; color:#dbeafe; border:1px solid rgba(148,163,184,.25); }
.gw-pill[data-variant="apy"]{ background:#052e16; color:#bbf7d0; border-color:rgba(74,222,128,.25);}
.gw-pill[data-variant="lock"]{ background:#1e1b4b; color:#e9d5ff; border-color:rgba(196,181,253,.25);}
.gw-pill[data-variant="points"]{ background:#0b1220; color:#c7d2fe;}
.gw-tip { position:absolute; z-index:50; left:50%; transform:translateX(-50%); bottom:calc(100% + 8px);
white-space:nowrap; padding:.45rem .6rem; border-radius:10px; font:500 12px/1.2 system-ui; background:#111827; color:#e5e7eb;
border:1px solid rgba(255,255,255,.08); opacity:0; pointer-events:none; transition:opacity .15s ease; }
.gw-pill:hover .gw-tip{opacity:1}
APY:
—
Demo APY from pool/index data (not financial advice)
Lock:
—
Indicative lock period for staking program
Points:
—
Cumulative participation points (demo)
(async function(){
const pills = document.getElementById('gw-pills');
// Anchor: place after #kpi-live if present; else after first h1
try {
const kpi = document.getElementById('kpi-live');
const h1 = document.querySelector('h1');
if (kpi) kpi.insertAdjacentElement('afterend', pills);
else if (h1) h1.insertAdjacentElement('afterend', pills);
} catch {}
const REL = (p)=>'data/'+p, LOCAL = (p)=>'http://127.0.0.1:5199/'+p;
const getJSON = async (p)=> {
const tryOne = (u)=>fetch(u+(u.includes('?')?'&':'?')+'_cb='+Date.now(),{cache:'no-store'})
.then(r=>r.ok?r.json():Promise.reject());
try { return await tryOne(REL(p)); } catch { try { return await tryOne(LOCAL(p)); } catch { return null; } }
};
const pool = await getJSON('pool.json') || {};
const idx = await getJSON('index.json') || {};
// Points (from index.json if available)
const pts = (typeof idx.points === 'number') ? idx.points : null;
// Lock days (optional)
const lock = (typeof idx.lock_days === 'number') ? idx.lock_days : null;
// APY: prefer explicit idx.apy else demo from pool totals
let apy = (typeof idx.apy === 'number') ? idx.apy : null;
if (apy == null && typeof pool.total_earned === 'number' && typeof pool.total_staked === 'number' && pool.total_staked > 0){
apy = (pool.total_earned / pool.total_staked) * 100; // lifetime demo %
}
// Paint values
const setOrHide = (id, val, fmt=(x)=>x)=> {
const el = document.getElementById(id);
const wrap = el?.closest('.gw-pill');
if (!el || !wrap) return;
if (val==null || Number.isNaN(val)) { wrap.style.display='none'; return; }
el.textContent = fmt(val);
};
setOrHide('pill-apy-val', apy, (v)=> (v>=100? v.toFixed(0): v>=10? v.toFixed(1): v.toFixed(2)) + '%');
setOrHide('pill-lock-val', lock, (v)=> v + ' days');
setOrHide('pill-points-val', pts, (v)=> v.toLocaleString('en-AU'));
// If at least one pill visible, unhide the row
const visible = [...document.querySelectorAll('#gw-pills .gw-pill')].some(p=>p.style.display!=='none');
if (visible) pills.hidden = false;
// Wire Tokenomics button to open modal (inserted by Module B)
const btn = document.getElementById('pill-tokenomics');
if (btn) btn.addEventListener('click', ()=> {
const modal = document.getElementById('gw-tokenomics-modal');
if (modal) modal.showModal();
});
})();
Source:
repo
.gwave-pills { display:flex; flex-wrap:wrap; gap:.5rem; margin:.5rem 0 1rem; }
.gw-pill { position:relative; padding:.4rem .6rem; border-radius:999px; font:600 12px/1 system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial;
background:#0f172a; color:#dbeafe; border:1px solid rgba(148,163,184,.25); }
.gw-pill[data-variant="apy"]{ background:#052e16; color:#bbf7d0; border-color:rgba(74,222,128,.25);}
.gw-pill[data-variant="lock"]{ background:#1e1b4b; color:#e9d5ff; border-color:rgba(196,181,253,.25);}
.gw-pill[data-variant="points"]{ background:#0b1220; color:#c7d2fe;}
.gw-tip { position:absolute; z-index:50; left:50%; transform:translateX(-50%); bottom:calc(100% + 8px);
white-space:nowrap; padding:.45rem .6rem; border-radius:10px; font:500 12px/1.2 system-ui; background:#111827; color:#e5e7eb;
border:1px solid rgba(255,255,255,.08); opacity:0; pointer-events:none; transition:opacity .15s ease; }
.gw-pill:hover .gw-tip{opacity:1}
APY:
—
Demo APY from pool/index data (not financial advice)
Lock:
—
Indicative lock period for staking program
Points:
—
Cumulative participation points (demo)
(async function(){
const pills = document.getElementById('gw-pills');
// Anchor: place after #kpi-live if present; else after first h1
try {
const kpi = document.getElementById('kpi-live');
const h1 = document.querySelector('h1');
if (kpi) kpi.insertAdjacentElement('afterend', pills);
else if (h1) h1.insertAdjacentElement('afterend', pills);
} catch {}
const REL = (p)=>'data/'+p, LOCAL = (p)=>'http://127.0.0.1:5199/'+p;
const getJSON = async (p)=> {
const tryOne = (u)=>fetch(u+(u.includes('?')?'&':'?')+'_cb='+Date.now(),{cache:'no-store'})
.then(r=>r.ok?r.json():Promise.reject());
try { return await tryOne(REL(p)); } catch { try { return await tryOne(LOCAL(p)); } catch { return null; } }
};
const pool = await getJSON('pool.json') || {};
const idx = await getJSON('index.json') || {};
// Points (from index.json if available)
const pts = (typeof idx.points === 'number') ? idx.points : null;
// Lock days (optional)
const lock = (typeof idx.lock_days === 'number') ? idx.lock_days : null;
// APY: prefer explicit idx.apy else demo from pool totals
let apy = (typeof idx.apy === 'number') ? idx.apy : null;
if (apy == null && typeof pool.total_earned === 'number' && typeof pool.total_staked === 'number' && pool.total_staked > 0){
apy = (pool.total_earned / pool.total_staked) * 100; // lifetime demo %
}
// Paint values
const setOrHide = (id, val, fmt=(x)=>x)=> {
const el = document.getElementById(id);
const wrap = el?.closest('.gw-pill');
if (!el || !wrap) return;
if (val==null || Number.isNaN(val)) { wrap.style.display='none'; return; }
el.textContent = fmt(val);
};
setOrHide('pill-apy-val', apy, (v)=> (v>=100? v.toFixed(0): v>=10? v.toFixed(1): v.toFixed(2)) + '%');
setOrHide('pill-lock-val', lock, (v)=> v + ' days');
setOrHide('pill-points-val', pts, (v)=> v.toLocaleString('en-AU'));
// If at least one pill visible, unhide the row
const visible = [...document.querySelectorAll('#gw-pills .gw-pill')].some(p=>p.style.display!=='none');
if (visible) pills.hidden = false;
// Wire Tokenomics button to open modal (inserted by Module B)
const btn = document.getElementById('pill-tokenomics');
if (btn) btn.addEventListener('click', ()=> {
const modal = document.getElementById('gw-tokenomics-modal');
if (modal) modal.showModal();
});
})();
.gwave-pills { display:flex; flex-wrap:wrap; gap:.5rem; margin:.5rem 0 1rem; }
.gw-pill { position:relative; padding:.4rem .6rem; border-radius:999px; font:600 12px/1 system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial;
background:#0f172a; color:#dbeafe; border:1px solid rgba(148,163,184,.25); }
.gw-pill[data-variant="apy"]{ background:#052e16; color:#bbf7d0; border-color:rgba(74,222,128,.25);}
.gw-pill[data-variant="lock"]{ background:#1e1b4b; color:#e9d5ff; border-color:rgba(196,181,253,.25);}
.gw-pill[data-variant="points"]{ background:#0b1220; color:#c7d2fe;}
.gw-tip { position:absolute; z-index:50; left:50%; transform:translateX(-50%); bottom:calc(100% + 8px);
white-space:nowrap; padding:.45rem .6rem; border-radius:10px; font:500 12px/1.2 system-ui; background:#111827; color:#e5e7eb;
border:1px solid rgba(255,255,255,.08); opacity:0; pointer-events:none; transition:opacity .15s ease; }
.gw-pill:hover .gw-tip{opacity:1}
APY:
—
Demo APY from pool/index data (not financial advice)
Lock:
—
Indicative lock period for staking program
Points:
—
Cumulative participation points (demo)
(async function(){
const pills = document.getElementById('gw-pills');
// Anchor: place after #kpi-live if present; else after first h1
try {
const kpi = document.getElementById('kpi-live');
const h1 = document.querySelector('h1');
if (kpi) kpi.insertAdjacentElement('afterend', pills);
else if (h1) h1.insertAdjacentElement('afterend', pills);
} catch {}
const REL = (p)=>'data/'+p, LOCAL = (p)=>'http://127.0.0.1:5199/'+p;
const getJSON = async (p)=> {
const tryOne = (u)=>fetch(u+(u.includes('?')?'&':'?')+'_cb='+Date.now(),{cache:'no-store'})
.then(r=>r.ok?r.json():Promise.reject());
try { return await tryOne(REL(p)); } catch { try { return await tryOne(LOCAL(p)); } catch { return null; } }
};
const pool = await getJSON('pool.json') || {};
const idx = await getJSON('index.json') || {};
// Points (from index.json if available)
const pts = (typeof idx.points === 'number') ? idx.points : null;
// Lock days (optional)
const lock = (typeof idx.lock_days === 'number') ? idx.lock_days : null;
// APY: prefer explicit idx.apy else demo from pool totals
let apy = (typeof idx.apy === 'number') ? idx.apy : null;
if (apy == null && typeof pool.total_earned === 'number' && typeof pool.total_staked === 'number' && pool.total_staked > 0){
apy = (pool.total_earned / pool.total_staked) * 100; // lifetime demo %
}
// Paint values
const setOrHide = (id, val, fmt=(x)=>x)=> {
const el = document.getElementById(id);
const wrap = el?.closest('.gw-pill');
if (!el || !wrap) return;
if (val==null || Number.isNaN(val)) { wrap.style.display='none'; return; }
el.textContent = fmt(val);
};
setOrHide('pill-apy-val', apy, (v)=> (v>=100? v.toFixed(0): v>=10? v.toFixed(1): v.toFixed(2)) + '%');
setOrHide('pill-lock-val', lock, (v)=> v + ' days');
setOrHide('pill-points-val', pts, (v)=> v.toLocaleString('en-AU'));
// If at least one pill visible, unhide the row
const visible = [...document.querySelectorAll('#gw-pills .gw-pill')].some(p=>p.style.display!=='none');
if (visible) pills.hidden = false;
// Wire Tokenomics button to open modal (inserted by Module B)
const btn = document.getElementById('pill-tokenomics');
if (btn) btn.addEventListener('click', ()=> {
const modal = document.getElementById('gw-tokenomics-modal');
if (modal) modal.showModal();
});
})();
.gwave-pills { display:flex; flex-wrap:wrap; gap:.5rem; margin:.5rem 0 1rem; }
.gw-pill { position:relative; padding:.4rem .6rem; border-radius:999px; font:600 12px/1 system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial;
background:#0f172a; color:#dbeafe; border:1px solid rgba(148,163,184,.25); }
.gw-pill[data-variant="apy"]{ background:#052e16; color:#bbf7d0; border-color:rgba(74,222,128,.25);}
.gw-pill[data-variant="lock"]{ background:#1e1b4b; color:#e9d5ff; border-color:rgba(196,181,253,.25);}
.gw-pill[data-variant="points"]{ background:#0b1220; color:#c7d2fe;}
.gw-tip { position:absolute; z-index:50; left:50%; transform:translateX(-50%); bottom:calc(100% + 8px);
white-space:nowrap; padding:.45rem .6rem; border-radius:10px; font:500 12px/1.2 system-ui; background:#111827; color:#e5e7eb;
border:1px solid rgba(255,255,255,.08); opacity:0; pointer-events:none; transition:opacity .15s ease; }
.gw-pill:hover .gw-tip{opacity:1}
APY:
—
Demo APY from pool/index data (not financial advice)
Lock:
—
Indicative lock period for staking program
Points:
—
Cumulative participation points (demo)
(async function(){
const pills = document.getElementById('gw-pills');
// Anchor: place after #kpi-live if present; else after first h1
try {
const kpi = document.getElementById('kpi-live');
const h1 = document.querySelector('h1');
if (kpi) kpi.insertAdjacentElement('afterend', pills);
else if (h1) h1.insertAdjacentElement('afterend', pills);
} catch {}
const REL = (p)=>'data/'+p, LOCAL = (p)=>'http://127.0.0.1:5199/'+p;
const getJSON = async (p)=> {
const tryOne = (u)=>fetch(u+(u.includes('?')?'&':'?')+'_cb='+Date.now(),{cache:'no-store'})
.then(r=>r.ok?r.json():Promise.reject());
try { return await tryOne(REL(p)); } catch { try { return await tryOne(LOCAL(p)); } catch { return null; } }
};
const pool = await getJSON('pool.json') || {};
const idx = await getJSON('index.json') || {};
// Points (from index.json if available)
const pts = (typeof idx.points === 'number') ? idx.points : null;
// Lock days (optional)
const lock = (typeof idx.lock_days === 'number') ? idx.lock_days : null;
// APY: prefer explicit idx.apy else demo from pool totals
let apy = (typeof idx.apy === 'number') ? idx.apy : null;
if (apy == null && typeof pool.total_earned === 'number' && typeof pool.total_staked === 'number' && pool.total_staked > 0){
apy = (pool.total_earned / pool.total_staked) * 100; // lifetime demo %
}
// Paint values
const setOrHide = (id, val, fmt=(x)=>x)=> {
const el = document.getElementById(id);
const wrap = el?.closest('.gw-pill');
if (!el || !wrap) return;
if (val==null || Number.isNaN(val)) { wrap.style.display='none'; return; }
el.textContent = fmt(val);
};
setOrHide('pill-apy-val', apy, (v)=> (v>=100? v.toFixed(0): v>=10? v.toFixed(1): v.toFixed(2)) + '%');
setOrHide('pill-lock-val', lock, (v)=> v + ' days');
setOrHide('pill-points-val', pts, (v)=> v.toLocaleString('en-AU'));
// If at least one pill visible, unhide the row
const visible = [...document.querySelectorAll('#gw-pills .gw-pill')].some(p=>p.style.display!=='none');
if (visible) pills.hidden = false;
// Wire Tokenomics button to open modal (inserted by Module B)
const btn = document.getElementById('pill-tokenomics');
if (btn) btn.addEventListener('click', ()=> {
const modal = document.getElementById('gw-tokenomics-modal');
if (modal) modal.showModal();
});
})();
.gwave-pills { display:flex; flex-wrap:wrap; gap:.5rem; margin:.5rem 0 1rem; }
.gw-pill { position:relative; padding:.4rem .6rem; border-radius:999px; font:600 12px/1 system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial;
background:#0f172a; color:#dbeafe; border:1px solid rgba(148,163,184,.25); }
.gw-pill[data-variant="apy"]{ background:#052e16; color:#bbf7d0; border-color:rgba(74,222,128,.25);}
.gw-pill[data-variant="lock"]{ background:#1e1b4b; color:#e9d5ff; border-color:rgba(196,181,253,.25);}
.gw-pill[data-variant="points"]{ background:#0b1220; color:#c7d2fe;}
.gw-tip { position:absolute; z-index:50; left:50%; transform:translateX(-50%); bottom:calc(100% + 8px);
white-space:nowrap; padding:.45rem .6rem; border-radius:10px; font:500 12px/1.2 system-ui; background:#111827; color:#e5e7eb;
border:1px solid rgba(255,255,255,.08); opacity:0; pointer-events:none; transition:opacity .15s ease; }
.gw-pill:hover .gw-tip{opacity:1}
APY:
—
Demo APY from pool/index data (not financial advice)
Lock:
—
Indicative lock period for staking program
Points:
—
Cumulative participation points (demo)
(async function(){
const pills = document.getElementById('gw-pills');
// Anchor: place after #kpi-live if present; else after first h1
try {
const kpi = document.getElementById('kpi-live');
const h1 = document.querySelector('h1');
if (kpi) kpi.insertAdjacentElement('afterend', pills);
else if (h1) h1.insertAdjacentElement('afterend', pills);
} catch {}
const REL = (p)=>'data/'+p, LOCAL = (p)=>'http://127.0.0.1:5199/'+p;
const getJSON = async (p)=> {
const tryOne = (u)=>fetch(u+(u.includes('?')?'&':'?')+'_cb='+Date.now(),{cache:'no-store'})
.then(r=>r.ok?r.json():Promise.reject());
try { return await tryOne(REL(p)); } catch { try { return await tryOne(LOCAL(p)); } catch { return null; } }
};
const pool = await getJSON('pool.json') || {};
const idx = await getJSON('index.json') || {};
// Points (from index.json if available)
const pts = (typeof idx.points === 'number') ? idx.points : null;
// Lock days (optional)
const lock = (typeof idx.lock_days === 'number') ? idx.lock_days : null;
// APY: prefer explicit idx.apy else demo from pool totals
let apy = (typeof idx.apy === 'number') ? idx.apy : null;
if (apy == null && typeof pool.total_earned === 'number' && typeof pool.total_staked === 'number' && pool.total_staked > 0){
apy = (pool.total_earned / pool.total_staked) * 100; // lifetime demo %
}
// Paint values
const setOrHide = (id, val, fmt=(x)=>x)=> {
const el = document.getElementById(id);
const wrap = el?.closest('.gw-pill');
if (!el || !wrap) return;
if (val==null || Number.isNaN(val)) { wrap.style.display='none'; return; }
el.textContent = fmt(val);
};
setOrHide('pill-apy-val', apy, (v)=> (v>=100? v.toFixed(0): v>=10? v.toFixed(1): v.toFixed(2)) + '%');
setOrHide('pill-lock-val', lock, (v)=> v + ' days');
setOrHide('pill-points-val', pts, (v)=> v.toLocaleString('en-AU'));
// If at least one pill visible, unhide the row
const visible = [...document.querySelectorAll('#gw-pills .gw-pill')].some(p=>p.style.display!=='none');
if (visible) pills.hidden = false;
// Wire Tokenomics button to open modal (inserted by Module B)
const btn = document.getElementById('pill-tokenomics');
if (btn) btn.addEventListener('click', ()=> {
const modal = document.getElementById('gw-tokenomics-modal');
if (modal) modal.showModal();
});
})();
LIVE
.gwave-pills { display:flex; flex-wrap:wrap; gap:.5rem; margin:.5rem 0 1rem; }
.gw-pill { position:relative; padding:.4rem .6rem; border-radius:999px; font:600 12px/1 system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial;
background:#0f172a; color:#dbeafe; border:1px solid rgba(148,163,184,.25); }
.gw-pill[data-variant="apy"]{ background:#052e16; color:#bbf7d0; border-color:rgba(74,222,128,.25);}
.gw-pill[data-variant="lock"]{ background:#1e1b4b; color:#e9d5ff; border-color:rgba(196,181,253,.25);}
.gw-pill[data-variant="points"]{ background:#0b1220; color:#c7d2fe;}
.gw-tip { position:absolute; z-index:50; left:50%; transform:translateX(-50%); bottom:calc(100% + 8px);
white-space:nowrap; padding:.45rem .6rem; border-radius:10px; font:500 12px/1.2 system-ui; background:#111827; color:#e5e7eb;
border:1px solid rgba(255,255,255,.08); opacity:0; pointer-events:none; transition:opacity .15s ease; }
.gw-pill:hover .gw-tip{opacity:1}
APY:
—
Demo APY from pool/index data (not financial advice)
Lock:
—
Indicative lock period for staking program
Points:
—
Cumulative participation points (demo)
(async function(){
const pills = document.getElementById('gw-pills');
// Anchor: place after #kpi-live if present; else after first h1
try {
const kpi = document.getElementById('kpi-live');
const h1 = document.querySelector('h1');
if (kpi) kpi.insertAdjacentElement('afterend', pills);
else if (h1) h1.insertAdjacentElement('afterend', pills);
} catch {}
const REL = (p)=>'data/'+p, LOCAL = (p)=>'http://127.0.0.1:5199/'+p;
const getJSON = async (p)=> {
const tryOne = (u)=>fetch(u+(u.includes('?')?'&':'?')+'_cb='+Date.now(),{cache:'no-store'})
.then(r=>r.ok?r.json():Promise.reject());
try { return await tryOne(REL(p)); } catch { try { return await tryOne(LOCAL(p)); } catch { return null; } }
};
const pool = await getJSON('pool.json') || {};
const idx = await getJSON('index.json') || {};
// Points (from index.json if available)
const pts = (typeof idx.points === 'number') ? idx.points : null;
// Lock days (optional)
const lock = (typeof idx.lock_days === 'number') ? idx.lock_days : null;
// APY: prefer explicit idx.apy else demo from pool totals
let apy = (typeof idx.apy === 'number') ? idx.apy : null;
if (apy == null && typeof pool.total_earned === 'number' && typeof pool.total_staked === 'number' && pool.total_staked > 0){
apy = (pool.total_earned / pool.total_staked) * 100; // lifetime demo %
}
// Paint values
const setOrHide = (id, val, fmt=(x)=>x)=> {
const el = document.getElementById(id);
const wrap = el?.closest('.gw-pill');
if (!el || !wrap) return;
if (val==null || Number.isNaN(val)) { wrap.style.display='none'; return; }
el.textContent = fmt(val);
};
setOrHide('pill-apy-val', apy, (v)=> (v>=100? v.toFixed(0): v>=10? v.toFixed(1): v.toFixed(2)) + '%');
setOrHide('pill-lock-val', lock, (v)=> v + ' days');
setOrHide('pill-points-val', pts, (v)=> v.toLocaleString('en-AU'));
// If at least one pill visible, unhide the row
const visible = [...document.querySelectorAll('#gw-pills .gw-pill')].some(p=>p.style.display!=='none');
if (visible) pills.hidden = false;
// Wire Tokenomics button to open modal (inserted by Module B)
const btn = document.getElementById('pill-tokenomics');
if (btn) btn.addEventListener('click', ()=> {
const modal = document.getElementById('gw-tokenomics-modal');
if (modal) modal.showModal();
});
})();
— Updated: loading…
.gwave-pills { display:flex; flex-wrap:wrap; gap:.5rem; margin:.5rem 0 1rem; }
.gw-pill { position:relative; padding:.4rem .6rem; border-radius:999px; font:600 12px/1 system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial;
background:#0f172a; color:#dbeafe; border:1px solid rgba(148,163,184,.25); }
.gw-pill[data-variant="apy"]{ background:#052e16; color:#bbf7d0; border-color:rgba(74,222,128,.25);}
.gw-pill[data-variant="lock"]{ background:#1e1b4b; color:#e9d5ff; border-color:rgba(196,181,253,.25);}
.gw-pill[data-variant="points"]{ background:#0b1220; color:#c7d2fe;}
.gw-tip { position:absolute; z-index:50; left:50%; transform:translateX(-50%); bottom:calc(100% + 8px);
white-space:nowrap; padding:.45rem .6rem; border-radius:10px; font:500 12px/1.2 system-ui; background:#111827; color:#e5e7eb;
border:1px solid rgba(255,255,255,.08); opacity:0; pointer-events:none; transition:opacity .15s ease; }
.gw-pill:hover .gw-tip{opacity:1}
APY:
—
Demo APY from pool/index data (not financial advice)
Lock:
—
Indicative lock period for staking program
Points:
—
Cumulative participation points (demo)
(async function(){
const pills = document.getElementById('gw-pills');
// Anchor: place after #kpi-live if present; else after first h1
try {
const kpi = document.getElementById('kpi-live');
const h1 = document.querySelector('h1');
if (kpi) kpi.insertAdjacentElement('afterend', pills);
else if (h1) h1.insertAdjacentElement('afterend', pills);
} catch {}
const REL = (p)=>'data/'+p, LOCAL = (p)=>'http://127.0.0.1:5199/'+p;
const getJSON = async (p)=> {
const tryOne = (u)=>fetch(u+(u.includes('?')?'&':'?')+'_cb='+Date.now(),{cache:'no-store'})
.then(r=>r.ok?r.json():Promise.reject());
try { return await tryOne(REL(p)); } catch { try { return await tryOne(LOCAL(p)); } catch { return null; } }
};
const pool = await getJSON('pool.json') || {};
const idx = await getJSON('index.json') || {};
// Points (from index.json if available)
const pts = (typeof idx.points === 'number') ? idx.points : null;
// Lock days (optional)
const lock = (typeof idx.lock_days === 'number') ? idx.lock_days : null;
// APY: prefer explicit idx.apy else demo from pool totals
let apy = (typeof idx.apy === 'number') ? idx.apy : null;
if (apy == null && typeof pool.total_earned === 'number' && typeof pool.total_staked === 'number' && pool.total_staked > 0){
apy = (pool.total_earned / pool.total_staked) * 100; // lifetime demo %
}
// Paint values
const setOrHide = (id, val, fmt=(x)=>x)=> {
const el = document.getElementById(id);
const wrap = el?.closest('.gw-pill');
if (!el || !wrap) return;
if (val==null || Number.isNaN(val)) { wrap.style.display='none'; return; }
el.textContent = fmt(val);
};
setOrHide('pill-apy-val', apy, (v)=> (v>=100? v.toFixed(0): v>=10? v.toFixed(1): v.toFixed(2)) + '%');
setOrHide('pill-lock-val', lock, (v)=> v + ' days');
setOrHide('pill-points-val', pts, (v)=> v.toLocaleString('en-AU'));
// If at least one pill visible, unhide the row
const visible = [...document.querySelectorAll('#gw-pills .gw-pill')].some(p=>p.style.display!=='none');
if (visible) pills.hidden = false;
// Wire Tokenomics button to open modal (inserted by Module B)
const btn = document.getElementById('pill-tokenomics');
if (btn) btn.addEventListener('click', ()=> {
const modal = document.getElementById('gw-tokenomics-modal');
if (modal) modal.showModal();
});
})();